【SpringBoot】SpringMVC && 请求注解详解 && 响应注解详解 && Lombok

文章目录

  • [Ⅰ. 什么是 Spring MVC](#Ⅰ. 什么是 Spring MVC)
  • [Ⅱ. 请求](#Ⅱ. 请求)
    • [一、路由映射 `@RequestMapping`](#一、路由映射 @RequestMapping)
      • [📚 常见属性详解](#📚 常见属性详解)
      • [① 指定 URL 路径(基本用法)](#① 指定 URL 路径(基本用法))
      • [② 指定具体的请求方法](#② 指定具体的请求方法)
      • [③ 指定多个 URL 和请求方法](#③ 指定多个 URL 和请求方法)
      • [④ 带参数约束的请求映射](#④ 带参数约束的请求映射)
      • [🔄 其它相关注解](#🔄 其它相关注解)
    • [二、`Postman` 的使用](#二、Postman 的使用)
    • 三、注意事项
    • [四、后端参数映射 `@RequestParam`](#四、后端参数映射 @RequestParam)
    • [五、传递 `json` 对象数据](#五、传递 json 对象数据)
      • [① 使用 `Jackson` 原生接口](#① 使用 Jackson 原生接口)
      • [② 使用注解 `@RequestBody`](#② 使用注解 @RequestBody)
    • [六、获取 URL 中的参数 `@PathVariable`](#六、获取 URL 中的参数 @PathVariable)
    • [七、上传文件 `@RequestPart` && `MultipartFile`](#七、上传文件 @RequestPart && MultipartFile)
    • [八、获取 cookie 和 session](#八、获取 cookie 和 session)
      • [① 原生接口获取 cookie](#① 原生接口获取 cookie)
      • [② 使用注解 `@CookieValue`](#② 使用注解 @CookieValue)
      • [③ 设置和获取 session](#③ 设置和获取 session)
      • 💥注意事项
    • [九、获取报头 `@RequestHeader`](#九、获取报头 @RequestHeader)
  • [Ⅲ. 响应](#Ⅲ. 响应)
  • 总结
  • 拓展:Lombok

Ⅰ. 什么是 Spring MVC

首先 MVCModel View Controller 的缩写,它是软件工程中的一种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分,如下图所示:

  • View(视图):指在应用程序中专门用来与浏览器进行交互,展示数据的资源。
  • Model(模型):是应用程序的主体部分,用来处理程序中数据逻辑的部分。
  • Controller(控制器):可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型。

Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从一开始就包含在 Spring 框架中。它的正式名称 SpringWeb MVC 来自其源模块的名称(Spring-webmvc),但它通常被称为 Spring MVC

简单的说,Spring MVC 是对 MVC 思想的具体实现,它本质上是一个 Web 框架

什么是 Servlet 呢❓❓❓

Servlet 是一种实现动态页面的技术。准确来讲 Servlet 是一套 JavaWeb 开发的规范,或者说是一套 JavaWeb 开发的技术标准。只有规范并不能做任何事情,必须要有人去实现它.所谓实现 Servlet 规范,就是真正编写代码去实现 Servlet 规范提到的各种功能,包括类、方法、属性等。Servlet 规范是开放的,除了 Sun 公司,其它公司也可以实现 Servlet 规范,目前常见的实现了 Servlet 规范的产品包括 TomcatWeblogicJettyJbossWebSphere 等,它们都被称为 "Servlet容器 ",用来管理程序员编写的 Servlet 类。

此外要区分,Spring Boot 是开发平台。Spring BootSpring MVC 包进来了,让我们用起来更轻松、更快速、更少配置,相当于 Spring Boot 是一个 "装修公司",而 Spring MVC 只是其中用来做 "Web 层装修"的技术

名称 本质 作用
Spring 核心(Spring Framework) 🌱 IoC + AOP 的核心容器 管理 Bean、提供依赖注入、面向切面编程
Spring MVC 🌐 基于 Servlet 的 Web 框架 实现 Web 请求处理(Controller + DispatcherServlet)
Spring Boot 🚀 快速开发脚手架 简化配置、自动装配、快速构建 Spring 应用

Ⅱ. 请求

一、路由映射 @RequestMapping

@RequestMapping 既可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是 类路径 + 方法路径

@RequestMapping 标识一个 :设置映射请求的请求路径的初始信息

@RequestMapping 标识一个方法 :设置映射请求请求路径的具体信息

java 复制代码
@RequestMapping("/user") 
@RestController 
public class UserController { 
    @RequestMapping("/sayHi") 
    public String sayHi(){ 
        return "hello,Spring MVC"; 
    } 
}

访问地址:http://127.0.0.1:8080/user/sayHi

📚 常见属性详解

属性 作用 示例
value / path 指定映射的 URL /users
method 指定请求方法 RequestMethod.GET
params 指定请求中必须包含某些参数值 params="id"
headers 指定请求中必须包含某些报头字段 headers="Content-Type=application/json"
produces 指定响应类型 produces="application/json"
consumes 指定请求的提交内容类型 consumes="application/json"

💥注意事项: spring 对于 ListMap、自定义类型等返回值,默认返回给前端的都是 json 格式 ,如果需要返回其它格式的响应,则需要通过 @RequestMapping 中的 produces 属性来设定!

① 指定 URL 路径(基本用法)

java 复制代码
@RequestMapping("/login")
    public String loginPage() {
        return "login.html";
}

② 指定具体的请求方法

java 复制代码
@RequestMapping(value = "/user", method = RequestMethod.GET)
public User getUser() {
    return new User();
}

现代推荐 :直接用更精简的注解,如 @GetMapping("/user")

③ 指定多个 URL 和请求方法

{} 来包含多个 URL 和请求方法:

java 复制代码
@RequestMapping(value = {"/login", "/signin"}, method = {RequestMethod.GET, RequestMethod.POST})
public String login() {
    return "login";
}

④ 带参数约束的请求映射

java 复制代码
@RequestMapping(value = "/search", params = "q")
public String search(@RequestParam String q) {
    return "搜索关键词:" + q;
}

🔄 其它相关注解

🔔 Spring 4.3 之后推荐使用这些简化版本,更清晰。

新注解 作用 等价于
@GetMapping 处理 GET 请求 @RequestMapping(method = RequestMethod.GET)
@PostMapping 处理 POST 请求 同上
@PutMapping 处理 PUT 请求 同上
@DeleteMapping 处理 DELETE 请求 同上

二、Postman 的使用

在使用 postman 传参的时候,通常有几种格式,这里列举三种陌生的:

  1. form-data (完整格式:multipart/form-data
    1. 表单提交的数据,通常用于提交图片、文件 等,对应 Content-Type: multipart/form-data
  2. x-www-form-urlencoded
    1. 表单提交的数据,通常用于提交纯文本比如账号、密码 等,对应 Content-Type: application/x-www-from-urlencoded
  3. raw
    1. 可以上传任意格式的文本 ,可以上传 textjsonxmlhtml 等。

三、注意事项

访问不同的路径,就是发送不同的请求。在发送请求时,可能会带一些参数,所以学习 Spring 的请求,主要是学习如何传递参数到后端以及后端如何接收,这里主要是使用浏览器和 Postman 来模拟。

  1. 使用基本类型 来接收参数时,参数必须传 (除 boolean 类型),否则会报 500 错误。
  2. 类型不匹配时,会报 400 错误。
  3. 如果只指定了 URL 路径而没有别的参数的话,则可以忽略属性 value,反之则必须加上!
  4. 当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置是不影响后端获取参数的结果

四、后端参数映射 @RequestParam

  1. @RequestParam 应用于以下场景:

    1. 前端通过 form表单GET请求参数 、或 POST的 x-www-form-urlencoded 方式提交

    2. 参数在 URL中key-value格式 中出现,如:

    Properties 复制代码
       /api/user?id=123&name=Tom
  2. 某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不一致,比如前端传递了一个 time 给后端,而后端是使用 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,就可以使用 @RequestParam 来重命名前后端的参数值,需要注意使用 @RequestParam 之后参数就默认变成了必传参数,要设置为非必传参数的话,要指定参数 required=false

    java 复制代码
    @RequestMapping("/d3")
    public String d3(@RequestParam(value="time", required=false) String createtime) { // 将time重命名为createtime,只对后端有效
        return createtime;
    }
  3. 传递集合参数 的时候,需要使用 @RequestParam 来绑定参数关系 ,因为默认情况下请求中参数名相同的多个值是封装到数组的,而如果要封装到集合的话,则需要用 @RequestParam 指定!

    java 复制代码
    @RequestMapping("/d5")
    public String d5(@RequestParam List<String> list) {
        return list.toString();
    }

五、传递 json 对象数据

Java 中常见的 JSON 库如下所示:

库名 速度 易用性 Spring兼容 特点
Jackson ⭐⭐⭐⭐ ⭐⭐⭐ ✅ 默认支持 强大、全面、Spring首选
Gson ⭐⭐⭐ ⭐⭐⭐⭐ 轻量、适合工具型项目
Fastjson2 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ 极速、国内常用、需注意版本安全
org.json ⭐⭐ ⭐⭐ 基础用法简单

其中 Spring Boot 内置了 Jackson,所以不需要引入依赖,只需要使用其核心类 ObjectMapper 来进行对象和 json 字符串的转化即可!

① 使用 Jackson 原生接口

这种操作一般不用,除非有特殊需求!

java 复制代码
public void ObjectToJson() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper(); // 创建jackson的核心类

    // writeValueAsString:将对象转化为JSON字符串
    StudentInfo stu = new StudentInfo();
    stu.setName("lirendada");
    stu.setAge(18);
    stu.setPasswd("123123");
    String jsonstr = mapper.writeValueAsString(stu);
    System.out.println("序列化结果:" + jsonstr);

    // readValue:将JSON字符串转化为对象
    StudentInfo new_stu = mapper.readValue(jsonstr, StudentInfo.class);
    System.out.println("反序列化结果:" + new_stu);
}

② 使用注解 @RequestBody

Spring 项目中,JSON 的序列化/反序列化工作几乎都由 Spring 自动完成 ,只需要使用 @RequestBody 即可,除非业务逻辑中需要特殊的 JSON 操作,否则一般无需手动操作 ObjectMapper

java 复制代码
@RequestMapping("/demo4")
@RestController
public class demo4 {
    // 请求 JSON → Java 对象(反序列化)
    @RequestMapping("/saveuser")
    public String saveUser(@RequestBody StudentInfo stu) {
        return "json对象保存成功:" + stu.toString();
    }
    
    // Java 对象 → JSON 响应(序列化)
    @RequestMapping("/getuser")
    public StudentInfo getUser() {
        // spring会自动将StudentInfo转化为JSON响应给前端
        return new StudentInfo("lirendada", 18, "123123"); 
    }
}

@RequestBody 通常处理以下场景:

  1. 前端使用 JSONXML 发送结构化数据(如使用 Axios、Fetch 或 Postman)
  2. 请求头为 Content-Type: application/json

六、获取 URL 中的参数 @PathVariable

首先需要在 @RequestMapping 中使用 {} 匹配一下 URL 中的参数 ,然后在方法参数列表中用 @PathVariable 指定对应的参数!

注意这个参数顺序是无序 的,并且如果方法参数要用别名,可以使用 @PathVariable value 属性进行绑定

java 复制代码
@RequestMapping("/url/{id}/{name}")
public String pathvar(@PathVariable Integer id,
                      @PathVariable("name") String username)  // 指定别名为username
{
    return "解析参数id:" + id + ", name:" + username;
}

七、上传文件 @RequestPart && MultipartFile

  1. MultipartFileSpring 定义的一个接口,表示上传的一个文件对象,它封装了文件上传时的所有关键信息,比如文件名、内容、文件大小、MIME 类型等。
  2. @RequestPart 通常处理前端通过 multipart/form-data 提交的数据,既有文件也有 JSON。
java 复制代码
@PostMapping("/upload")
public String upload(@RequestPart("file") MultipartFile file,
                     @RequestPart("user") User user)  throws IOException {
    System.out.println(file.getOriginalFilename()); // 获取文件原名
    System.out.println(file.getName());             // 获取请求时的键名
    System.out.println(file.getContentType());      // 获取文件类型

    // 将文件上传到指定路径
    file.transferTo(new File("E:/杂物文档/" + file.getOriginalFilename()));
    return "接收到的文件名为:" + file.getOriginalFilename();
}

CookieSession 之间主要是通过 SessionID 关联起来的,SessionIDCookieSession 之间的桥梁,如下图所示:

Spring MVC 是基于 ServletAPI 构建的原始Web框架,是在 Servlet 的基础上实现的.

其中 HttpServletRequestHttpServletResponseServlet 提供的两个类,同时也是 Spring MVC 方法的内置对象,需要时直接在方法中添加声明即可

  • HttpServletRequest 对象代表客户端的请求,当客户端通过 HTTP 协议访问服务器时,HTTP 请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
  • HttpServletResponse 对象代表服务器的响应,HTTP 响应的信息都在这个对象中,比如向客户端发送的数据、响应头、状态码等,通过这个对象提供的方法,可以获得服务器响应的所有内容。

获取 cookie 本质就是通过 HttpServletRequest 的接口来获得!

java 复制代码
@RequestMapping("/d1")
public String getcookie1(HttpServletRequest req) {
    // 获取请求中的所有cookie,使用数组的时候记得判断是否为空
    Cookie[] cookies = req.getCookies();
    if(cookies != null) {
        for(Cookie cookie : cookies) {
            System.out.println(cookie.getName() + ": " + cookie.getValue());
        }
    }
    return "返回cookies成功!";
}

② 使用注解 @CookieValue

注意如果没有在该注解中指定 cookie 的名称的话,则默认只能拿到一个 cookie

java 复制代码
@RequestMapping("/d2")
public String getcookie2(@CookieValue("liren") String liren,
                         @CookieValue("asd") String asd) {
    return "liren: " + liren + "<br>asd: " + asd;
}

③ 设置和获取 session

三种方式,分别用到 HttpServletRequest 类的 getSession()、参数列表中 HttpSession session 接收参数、注解 @SessionAttribute,如下所示:

java 复制代码
/**
 * 获取session对象,根据是否为空判断要不要创建新session
 */
@RequestMapping("/setsession")
public String setSession(HttpServletRequest req) {
    // 先获取session对象,设置为false,则不存在session就返回null,用于判断是否过期
    HttpSession session = req.getSession(false);
    if(session == null) {
        // 过期了,要创建新的session对象
        System.out.println("超时了!");
        session = req.getSession(true); // 这次获取session对象用true,则不存在会创建
        session.setMaxInactiveInterval(5); // 设置会话过期时间,单位为秒
    }
    session.setAttribute("liren", "lirendada_love_yt");
    return "session设置成功";
}

/**
 * 方式一:使用 HttpServletRequest 类的 getSession()
 */
@RequestMapping("/g1")
public String getsession1(HttpServletRequest req, HttpServletResponse resp) {
    HttpSession session = req.getSession(); // 默认为true,不存在会创建新session
    if(session != null && session.getAttribute("liren") != null) {
        return "liren: " + session.getAttribute("liren");
    }
    return "null";
}

/**
 * 方式二:直接在参数列表中获取HttpSession对象
 */
@RequestMapping("/g2")
public String getsession2(HttpSession session) {
    if(session != null && session.getAttribute("liren") != null) {
        return "liren: " + session.getAttribute("liren");
    }
    return "null";
}

/**
 * 方式三:使用注解 @SessionAttribute
 */
@RequestMapping("/g3")
public String getsession3(@SessionAttribute String liren) {
    return "liren: " + liren;
}

💥注意事项

  1. 每次访问 HttpSession 的实际内容时(比如读写属性、调用方法等)都会自动刷新它的失效倒计时 ,这个失效倒计时可以通过 setMaxInactiveInterval(int s) 进行设置,单位是秒。
  2. sessionid 在第一次创建 HttpSession 对象的时候生成 ,并且不需要手动在 HttpServletResponse 中设置 ,因为底层容器 Servlet 会自动设置!
  3. 通过 getSession(boolean iscreate) 中的 iscreate 参数可以灵活处理不同情况:
    1. 在需要第一次创建 HttpSession 对象的场景中,通常让 iscreatetrue,表示对象不存在时候创建新对象。
    2. 其它场景比如获取 HttpSession 对象的时候,通常就让 iscreatefalse,这样子就不会创建新对象。

九、获取报头 @RequestHeader

java 复制代码
/**
 * 方式一:使用HttpServletRequest的getHeader()方法
 */
@RequestMapping("/g1")
public String getHeader1(HttpServletRequest req) {
    return "User-Agent: " + req.getHeader("User-Agent");
}

/**
 * 方式二:使用注解@RequestHeader
 */
@RequestMapping("/g2")
public String getHeader2(@RequestHeader("User-Agent") String agent) {
    return "User-Agent: " + agent;
}

Ⅲ. 响应

  1. @RestController 指定这是一个进行了路由映射的类,并且指定该类返回非视图数据,而不是视图

    1. Spring 会对所有的类进行扫描,如果类加了注解 @RestControllerSpring 才会去看这个类里面的方法有没有加 @RequestMapping 这个注解,当然他的作用不止这一点,后面详细讲!

    java 复制代码
    @RestController   
    public class demo {
        @RequestMapping("hello")
        public String func() {
            return "liren!";
        }
    }
    1. 实际上 @RestController = @Controller + @ResponseBody ,这是为了实现 "前后端分离" 而引入的,因为现在前端大部分不需要后端来做,所以后端只需要返回前端约定好的数据即可,所以现在一般都直接 @RestController 来指定返回非视图数据 ,而单独使用 @Controller 的话则返回的是视图

      • @ResponseBody:可以放在类或者方法上面,表示类或者方法返回的是非视图数据,即返回一个 text/html 数据。
      • @Controller:定义一个控制器,在 spring 框架启动时加载,把这个对象交给 spring 管理,也就是进行路由映射。
  2. 什么情况下响应的是 json 格式❓❓❓

    1. 控制器加了 @RestController@ResponseBody
    返回值类型 返回 JSON 格式? 示例结果
    Map<String, ?> ✅ 是 JSON 对象
    List / 数组 ✅ 是 JSON 数组
    Object ✅ 是 JSON 对象
    String ⚠️ 特殊处理 默认会被当成字符串文本返回,而不是 JSON
    java 复制代码
      @ResponseBody
      @RequestMapping("/returnjson")
      public Map<String, String> returnjson() {
          HashMap<String, String> table = new HashMap<>();
          table.put("java", "good");
          table.put("cpp", "not good");
          table.put("redis", "not bad");
          return table;
      }
  3. 设置响应状态码 ,使用 HttpServletResponse 对象调用 setStatus() 即可。

    • 注意:状态码并不影响响应页面的展示!
  4. 设置响应报头 ,其中有些报头,比如设置响应类型,可以使用注解 @RequestMapping 中的属性 produces,而其它报头需要通过 HttpServletResponse 对象调用 setHeader() 来设置。

  5. 常见的响应格式方法如下所示:

场景类型 推荐返回方式
简单文本或标志返回("true"/"false") String + produces="text/html"
正常 REST 接口返回 JSON @RestController + 返回对象/Map/List
返回模板页面 @Controller + return "xxx.html"
要求精确控制响应头、状态码 ResponseEntity<String>

总结

拓展:Lombok

我们写一个 Java 实体类时,常常需要写一堆 GetterSetter、构造方法、toStringequalshashCode 等等,非常冗长,而 Lombok 可以 自动生成这些代码,你只需要写个注解

注解 功能
@Getter / @Setter 自动生成 getter/setter 方法
@ToString 自动生成 toString() 方法
@EqualsAndHashCode 自动生成 equals() 和 hashCode() 方法
@NoArgsConstructor 自动生成无参构造器
@AllArgsConstructor 自动生成全参构造器
@RequiredArgsConstructor 自动生成包含 final 字段的构造器
@Data 相当于同时加了:@Getter、@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor
@Builder 生成建造者模式的代码
@Slf4j 自动生成日志对象(log),方便日志打印

可以通过该网站引入依赖:https://mvnrepository.com/artifact/org.projectlombok/lombok

xml 复制代码
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
</dependency>
相关推荐
indexsunny1 小时前
互联网大厂Java求职面试实战:Spring Boot微服务与Redis缓存场景解析
java·spring boot·redis·缓存·微服务·消息队列·电商
无心水1 小时前
【分布式利器:腾讯TSF】7、TSF高级部署策略全解析:蓝绿/灰度发布落地+Jenkins CI/CD集成(Java微服务实战)
java·人工智能·分布式·ci/cd·微服务·jenkins·腾讯tsf
28岁青春痘老男孩6 小时前
JDK8+SpringBoot2.x 升级 JDK 17 + Spring Boot 3.x
java·spring boot
方璧7 小时前
限流的算法
java·开发语言
元Y亨H7 小时前
Nacos - 服务注册
java·微服务
曲莫终7 小时前
Java VarHandle全面详解:从入门到精通
java·开发语言
天若有情6737 小时前
校园二手交易系统实战开发全记录(vue+SpringBoot+MySQL)
vue.js·spring boot·mysql
一心赚狗粮的宇叔7 小时前
中级软件开发工程师2025年度总结
java·大数据·oracle·c#
while(1){yan}7 小时前
MyBatis Generator
数据库·spring boot·java-ee·mybatis
奋进的芋圆7 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端