SpringBoot请求响应(1.29)

一、项目结构:

image-20260129165748570

  • static:静态资源目录,里面的 HTML、CSS、JS 等可以直接通过 URL 访问,比如:http://localhost:8080/page1.html
  • templates:模板文件目录,里面的 Thymeleaf、Freemarker 等模板文件,不能直接通过 URL 访问,必须通过 Controller 的 return "page2"; 这种方式转发才能渲染输出。

二、Thymeleaf:

1.概念

Thymeleaf 是 Spring Boot 官方推荐的现代服务器端 Java 模板引擎,它能让你在 HTML 中嵌入动态数据,实现前后端数据的无缝结合。

2.应用:

①在pom.xml中引入:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

②在html标签中加入:

<html lang="en" xmlns:th="http://www.thymeleaf.org">

③controller.PageController类:

@Controller//把当前类的实例化对象放入到IOC容器中
public class PageController {

    //@GetMapping("/page2")
    //@PostMapping("/page2") -->405
    @RequestMapping("/page2")//将HTTP请求映射到对应的Controller方法上
    public String page2(Map<String,Object> map){//map 等效于 request.setAttribute()
        System.out.println("page2");
        //1.
        map.put("name","小帅");
        map.put("age",11);
        //2.
        map.put("sex",true);
        //3.
        List<String> nameList = List.of("mao1","mao2","mao3");
        map.put("nameList",nameList);

        return "page2";//返回逻辑地址
    }
}

④templates.page2.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
     hello page2<br>
     <!--1.文本 -->
    <div th:text="'你好'+${name}"></div>
     <!--2. 条件判断 -->
    <div th:if ="${sex}">男</div>
    <div th:unless ="${sex}">女</div>
     <!--3. 遍历 -->
    <div th:each="str:${nameList}">
        <span th:text="${str}"></span>
    </div>
</body>
</body>
</html>

http://localhost:8080/page2

3.发送多种请求:

​ 若发两种请求,如同时发送GET、POST请求,则需更改@RequestMapping("/page2")

@RequestMapping(value = "/page2",method = {RequestMethod.GET,RequestMethod.POST})

4.在类上加@RequestMapping请求

@RequestMapping("/page2")
public class PageController {
    @RequestMapping("/page2")
    public String page2(Map<String,Object> map){
        System.out.println("page2"); 
        map.put("name","小帅");   
        return "page2";//返回逻辑地址
    }
}

完整路径 = 类上基础路径 + 方法上子路径 --->用于请求的分类

http://localhost:8080/page2/page2

补充:接收请求的注解:

  • @RequestMapping默认处理所有请求方式
  • @GetMapping仅处理 GET
  • @PostMapping仅处理 POST

三、Apifox:

前端发送的请求:

  • GET:@GetMapping 查询

  • POST:@PostMapping 添加

  • PUT:@PutMapping 修改

  • DELETE:@DeleteMapping 删除

  • PATCH:@PatchMapping 局部修改

小结:

​ 1.网页请求的本质只有 GET、POST 两种,除了GET请求,其他请求都是基于POST做的语义模拟。

​ 2.模拟的这些请求称为restful风格的请求,以前的请求post到后端后,具体是增删改哪一种,由后端自己定;

​ 现在用restful风格的请求,从前端我们就可以知道具体是哪一种请求了,无需后端额外判断

​ 3.浏览器在地址栏搜索URL点击<a>标签跳转,默认发起的都是 GET 请求

​ 浏览器中只有表单提交可以手动指定method="post"改为 POST 请求。

四、Controllerc参数传递

1.前端URL传递参数:localhost:8080/page2?username=mao&password=1234 --->get请求

PageController:

@Controller
public class PageController {
    @RequestMapping("/page2")
    public String page2(String username,String password,Map<String,Object> map){
        System.out.println("page2");

        Map<String, String> dataMap = new ConcurrentHashMap<>();
        dataMap.put("username",username);
        dataMap.put("password",password);

        map.put("dataMap", dataMap);

        return "page2";//返回逻辑地址
    }
}

page2.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
     hello page2<br>
     <div th:text="${dataMap.username}"></div>
     <div th:text="${dataMap.password}"></div>
</body>
</body>
</html>

(1)存储过程的叙述:

1.从URL中获取到username和password的值

2.先定义一个Map集合dataMap,存入username和password的kv

3.再把dataMap对象,存入AttributeMap中,键为"dataMap"

4.${dataMap} 直接获取 AttributeMap 中键为 dataMap 的 value,也就是你后端存的那个ConcurrentHashMap对象dataMap

<div th:text="${dataMap}"></div>

结果为:{password=1234, username=mao} --->为何乱序?---> HashMap 的线程安全版是无序的哈希表

5.语法约定:对Map 集合对象,使用${map对象.键名}的语法,等价于 Java 中的map对象.get("键名")

所以:

  • ${dataMap.username} → 等价于 → dataMap.get("username") → 取到值mao
  • ${dataMap.password} → 等价于 → dataMap.get("password") → 取到值1234

(2)若page2()方法中的参数username与前端传的参数名不一致,可以使用@RequestParam注解,使后端方法中的username与注解中的名一致,即与前端传的名一致。

@RequestMapping("/page2")
    public String page2(@RequestParam("username12") String username, String password, Map<String,Object> map){
        System.out.println("page2");

        Map<String, String> dataMap = new ConcurrentHashMap<>();
        dataMap.put("username",username);
        dataMap.put("password",password);

        map.put("dataMap", dataMap);

        return "page2";//返回逻辑地址
    }

http://localhost:8080/page2?username12=mao&password=1234

2.通过对象接收前端传来的参数:

新建User实体类:

@Data
public class User {
    private String username;
    private String password;
}

PageController:

@Controller
public class PageController {

    @RequestMapping("/page2")
    public String page2(User user, Map<String,Object> map){
        System.out.println("page2");

        Map<String, String> dataMap = new ConcurrentHashMap<>();
        dataMap.put("username", user.getUsername());
        dataMap.put("password", user.getPassword());

        map.put("dataMap", dataMap);

        return "page2";//返回逻辑地址
    }
}

http://localhost:8080/page2?username=mao1&password=123

Apifox测试:

image-20260129210716755

GET 请求:数据写在 URL 中

POST 请求:数据写在请求体(Request Body)中

3.JSON传参:

思考:localhost:8080/page2?username=mao1&password=123可以单个接也可以放在一个对象去接,但是js对象可以直接变成一个java对象,js对象映射java对象,后端再通过对象去接,而不是两个字符串再创建对象,再放里面放。

(1)JSON格式:

{
  "username": "bing",
  "age": 20,
  "isVip": true, 
  "remark": null,
  "hobby": ["篮球", "听歌", "编程"], 
  "scores": [80, 90, 95.5],   
  "addressInfo": { // 子对象:地址信息
    "province": "辽宁省",
    "city": "沈阳市"
  }
}

(2)JSON格式传入数据:

{
    "username":"maomaocong",
    "password":"12345"
}

PageController:

在对象前加入@RequestBody

@Controller
public class PageController {

    @RequestMapping("/page2")
    public String page2(@RequestBody User user, Map<String,Object> map){
        System.out.println("page2");

        Map<String, String> dataMap = new ConcurrentHashMap<>();
        dataMap.put("username", user.getUsername());
        dataMap.put("password", user.getPassword());

        map.put("dataMap", dataMap);

        return "page2";//返回逻辑地址
    }
}

后端往前端传数据

PageController:

在类上写@ResponseBody注解,方法返回值类型为Map<String, String>,返回其对象dataMap

@ResponseBody
@Controller
public class PageController {

    @RequestMapping("/page2")
    public Map<String, String> page2( User user){
        System.out.println("page2");

        Map<String, String> dataMap = new ConcurrentHashMap<>();
        dataMap.put("username", user.getUsername());
        dataMap.put("password", user.getPassword());

        return dataMap;//返回逻辑地址
    }

前端结果:{"password":"123","username":"mao"}

注意:

  • @ResponseBody → 返 JSON,不渲染页面,无需在 html 中取值;

  • 不加@ResponseBody → 渲染 html,需通过Map/Model传参,页面用 Thymeleaf 标签取值展示;

注解总结:

  1. @GetMapping("/page2")

  2. @PostMapping("/page2")

  3. @RequestMapping("/page2")

  4. @RequestParam("username12")

  5. @RequestBody

    @ResponseBody

posted on 2026-01-29 22:04  冬冬咚  阅读(1)  评论(0)    收藏  举报