SpringMVC-传参注解学习【详细全面、简单易懂无废话】

SpringMVC——前后端传参常用注解总结

文章目录

  • SpringMVC——前后端传参常用注解总结
    • 一、准备一个获取登录信息的案例
      • 1. 开发环境准备
      • 2. 新建Maven模块
      • 3. 在main下新建一个webapp目录
      • 4. 添加web.xml文件
      • 5.配置web.xml文件
      • 6. 在resources目录下创建springmvc.xml文件
      • 7. 在java目录下创建package(实体类、控制层)
      • 8. 在WEB-INF目录下新建文件夹thymeleaf
      • 9. 此时配置tomcat服务器,测试程序运行是否正常
    • 二、具体注解学习
      • 1. @RequestMapping
      • 2. @GetMapping
      • 3. @PostMapping
      • 4. @RequestParam
      • 5. @RequestBody
      • 6. @PathVariable
      • 7. @RestController
      • 7. @RestController

一、准备一个获取登录信息的案例

1. 开发环境准备

  • IDEA
  • Tomcat10
  • Maven
  • JDK17

2. 新建Maven模块

  • Maven记得配置为自己的本地Maven:Settings->Build->Build Tools->Maven

在这里插入图片描述

  • pom.xml文件中添加依赖,添加完记得刷新

    <!--打包方式:war-->
    <packaging>war</packaging>
    <!--依赖-->
    <dependencies>
        <!--springmvc依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>6.1.4</version>
        </dependency>
        <!--servlet依赖-->
        <dependency>
            <!--tomcat10版本使用jakarta-->
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <!--指定依赖的范围,provideed指该依赖会被第三方容器提供,不会打包的war包中-->
            <scope>provided</scope>
        </dependency>
        <!--logback依赖-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.5.3</version>
        </dependency>
        <!--thymeleaf和spring6整合依赖-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring6</artifactId>
            <version>3.1.2.RELEASE</version>
        </dependency>
        <!--处理json格式-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.17.2</version>
        </dependency>
    </dependencies>
    

3. 在main下新建一个webapp目录

在这里插入图片描述

  • 注意,在pom.xml文件依赖添加完后进行该步,会创建一个标准的webapp目录

    在这里插入图片描述

4. 添加web.xml文件

在这里插入图片描述

  • 点击Apply和Ok后出现该目录

    在这里插入图片描述

5.配置web.xml文件

  • DispatcherServlet是一个前端控制器。在Spring MVC中,它扮演了一个至关重要的角色。当用户在浏览器发出一个HTTP请求时,该请求会先到达DispatcherServlet。

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
             version="5.0">
        <!--配置前端控制器(DispatcherServlet)-->
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <!--DispatcherServlet是SpringMVC中处理HTTP请求的核心组件-->
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <!--指定了SpringMVC配置文件的路径(类的根路径)和名称(springmvc.xml)-->
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <!--指定该控制器在服务器启动时的启动优先级-->
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <!--例如/login这样的请求路径都会经过该控制器-->
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>
    

6. 在resources目录下创建springmvc.xml文件

在这里插入图片描述

  • 编写springmvc.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://www.springframework.org/schema/mvc
               http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!-- 开启注解驱动,改配置用于接收前端发来的JSON数据 -->
        <mvc:annotation-driven>
            <mvc:message-converters>
                <!-- 配置 JSON 消息转换器 -->
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                        <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                            <!-- 可以配置更多 Jackson ObjectMapper 的属性 -->
                            <property name="serializationInclusion" value="NON_NULL"/>
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    
        <!--配置组件扫描-->
        <context:component-scan base-package="pers.weiney.springmvc.controller"/>
        <!--配置视图解析器-->
        <bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
            <!--作用于视图渲染的过程中,可以设置视图渲染后输出时采用的编码字符集-->
            <property name="characterEncoding" value="UTF-8"/>
            <!--如果配置多个视图解析器,它来决定优先使用哪个视图解析器,它的值越小优先级越高-->
            <property name="order" value="1"/>
            <!--当 ThymeleafViewResolver 渲染模板时,会使用该模板引擎来解析、编译和渲染模板-->
            <property name="templateEngine">
                <bean class="org.thymeleaf.spring6.SpringTemplateEngine">
                    <!--用于指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器负责根据模板位置、模板资源名称、文件编码等信息,加载模板并对其进行解析-->
                    <property name="templateResolver">
                        <bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
                            <property name="prefix" value="/WEB-INF/thymeleaf/"/>
                            <property name="suffix" value=".html"/>
                            <property name="templateMode" value="HTML"/>
                            <property name="characterEncoding" value="UTF-8"/>
                        </bean>
                    </property>
                </bean>
            </property>
        </bean>
    
    </beans>
    

7. 在java目录下创建package(实体类、控制层)

在这里插入图片描述

在这里插入图片描述

  • pojo包下新建User.java类

    package pers.weiney.springmvc.pojo;
    
    /**
     * @author Weiney
     * @ToDo
     * @create 2024-07-31 15:47
     */
    public class User {
        
        private String username; // 用户名
        private String password; // 用户密码
    
        public User() {
        }
    
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
    
  • controller包下新建IndexController.java

    package pers.weiney.springmvc.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * @author Weiney
     * @ToDo
     * @create 2024-07-31 16:18
     */
    // Controller注解用于标识该控制器类,将其纳入Spring框架进行管理,控制器层负责处理前端HTTP请求,协调业务逻辑的处理
    @Controller
    public class IndexController {
    
        // 浏览器中访问http://localhost:9999/springmvc/,前端控制器会根据最后一个/,进行请求映射到该方法
        @RequestMapping("/")
        public String Index(){
            // 返回逻辑视图,视图解析器会将其转为物理视图,路径拼接成/WEB-INF/thymeleaf/index.html
            return "index";
        }
    }
    

8. 在WEB-INF目录下新建文件夹thymeleaf

在这里插入图片描述

  • 在该thymeleaf目录下新建html文件index.html

    <!DOCTYPE html>
    <html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>用户登录</title>
    </head>
    <body>
    <h1>用户登录</h1>
    <!--点击登录后会发出请求:http://localhost:9999/springmvc/user/login,且会在控制器中对应一个方法-->
    <form th:action="@{/user/login}" method="post">
        账号:<input type="text" name="username"><br>
        密码:<input type="password" name="password">
        <input type="submit" value="点击登录">
    </form>
    </body>
    </html>
    
  • 此时回到IndexController中新增一个方法,路径映射到该方法上

    @RequestMapping("/user/login")
    public String login(){
        // 获取参数,业务处理
    
        // 返回逻辑视图
        return "ok";
    }
    
  • 并编写一个用于登录成功返回的页面ok.html

    在这里插入图片描述

  • 内容如下:

    <!DOCTYPE html>
    <html lang="zh-cn" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>登录成功</title>
    </head>
    <body>
    <h1>登录成功</h1>
    </body>
    </html>
    

9. 此时配置tomcat服务器,测试程序运行是否正常

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 启动该服务器,浏览器中访问:http://localhost:8888/springmvc/

    在这里插入图片描述

二、具体注解学习

前言:注解式开发可以提高代码的可读性和可维护性,且开发过程中简化了大量配置文件和复杂的代码,框架的作用也体现在此,复杂的事情交给框架来做,我们直接使用框架封装好的类,提高开发效率。

1. @RequestMapping

  • 作用:将前端发送的请求映射到相应的处理方法上,从而实现对请求的处理和响应。

  • RequestMapping注解只能出现在类上或者方法上。

    • @RequestMapping("/user/login")
          public String login(){
              // 获取参数,业务处理
      
              // 返回逻辑视图
              return "ok";
          }
      
    • @RequestMapping("/user/register")
          public String register(){
              // 获取参数,业务处理
      
              // 返回逻辑视图
              return "ok";
          }
      
    • @Controller
      @RequestMapping("/user")
      public class IndexController {
      
          @RequestMapping("/login")
          public String login(){
              // 获取参数,业务处理
      
              // 返回逻辑视图
              return "ok";
          }
      
          @RequestMapping("/register")
          public String register(){
              // 获取参数,业务处理
      
              // 返回逻辑视图
              return "ok";
          }
      }
      
  • value属性:字符串数组,别名path

    • 多个不同的请求路径映射到同一个控制器的同一个方法上:

      @RequestMapping(value={"/page1", "/page2", "page3"})
      
    • 当只有一个请求路径"/page1"时:value={}可以不写,简写为"/page1"

      @RequestMapping("/page1")
      
    • value里的路径是支持模糊匹配的,这种模糊匹配称之为Ant风格

      • ?:代表任意一个字符,某些特殊字符不可以

        @RequestMapping("/a?c/login"),
        
      • *:代表0到N个任意字符

        @RequestMapping("/a*c/login")
        
      • **:代表0到N个任意字符,并且路径中可以出现路径分隔符 /

        @RequestMapping("/page1/**")
        
  • method属性:枚举类型数组

    public enum RequestMethod {
        GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
        // ...
    }
    
    • 如何使用:

      @RequestMapping("/user/login", method = RequestMethod.POST)
      // 同样method = RequestMethod.POST有简写形式,下文会有介绍
      public String login(){
          // 获取参数,业务处理
      
          // 返回逻辑视图
          return "ok";
      }
      
    • 作用:限制客户端的请求方式。如浏览器发送get请求,数据会显示在URL上,若是登录密码则有泄漏的可能性,因此此时需要发送post请求,请求的参数在请求体中,相对更安全。因此后端可以强制接收POST方式的请求,即在@RequestMapping注解中规定所需要的请求方式。

    • 若请求方式不一致,会报HTTP状态码:405错误,方法不允许。

  • params属性:和value属性类似,也是一个字符串数组,但params属性,要求浏览器发送的请求参数必须和params数组中的参数完全一致才可以映射到相应方法上。

    • 如何使用:4种表示方法

      // 1. 请求路径中必须包含username参数和password参数,才能映射到当前方法
      @RequestMapping(value="/login", params={"username", "password"}) 
      // 2. 请求路径中不能包含username参数,但需要有password参数,才能映射到当前方法
      @RequestMapping(value="/login", params={"!username", "password"}) 
      // 3. 请求路径中的username参数值必须为admin,且有password参数,才能映射到当前方法
      @RequestMapping(value="/login", params={"username=admin", "password"}) 
      // 4. 请求路径中的username参数值不是admin,且有password参数,才能映射到当前方法
      @RequestMapping(value="/login", params={"username!=admin", "password"}) 
      
    • 如果前端提交的参数,和后端要求的请求参数不一致,会出现HTTP状态码:400错误,请求参数格式不正确导致的。

  • headers属性:使用形式和params属性类似

    // 如请求头中必须包含Referer和Host
    // 浏览器中F12可以查看
    // Referer: http://localhost:8080/springmvc/
    // 键是Referer,值是http://localhost:8080/springmvc/
    // Host: localhost:8080,键是Host,值是localhost:8080
    @RequestMapping(value="/login", headers={"Referer", "Host"}) 
    

2. @GetMapping

  • 等同于:

    @RequestMapping("/login", method = RequestMethod.GET)
    
  • 使用此注解时,不需要指定method属性,且其他属性使用方法和@RequestMapping一致。

3. @PostMapping

  • 等同于:

    @RequestMapping("/login", method = RequestMethod.POST)
    
  • 除此外还有@PutMapping、@DeleteMapping等。

4. @RequestParam

  • 作用:获取浏览器提交的数据,如username、password等,将请求参数与方法上的形参映射。。

  • SpringMVC底层就是封装了Java的Servlet(Java编写的服务器端程序,可以交互式浏览和生成数据,生成动态Web内容),若用Servlet接口中的方法获取参数,如下:

    @PostMapping(value="/login")
    public String login(HttpServletRequest request){
        // 通过当前请求对象request获取提交的数据
        String username = ;
        String password = ;
        // ...
    }
    
  • 那么封装了Servlet的SpringMVC框架如何获取浏览器提交的参数呢?

    @RequestMapping("/user/login")
    public String login(
        ...
        String username,
        ...
        String password){
        // 获取参数,业务处理
        System.out.println("username: " + username + " \npassword: " + password);
        // 返回逻辑视图
        return "ok";
    }
    
  • 看一下该@RequestParam注解的源码

    @Target({ElementType.PARAMETER})
    @Retention(RetentionPolicy.RUNTIME) // 注解的保留方式
    @Documented // java生成说明文档时,声明是否显示该注解
    public @interface RequestParam {
        @AliasFor("name")
        String value() default "";
    
        @AliasFor("value")
        String name() default "";
    
        boolean required() default true;
    
        String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
    }
    
  • value属性(或name属性,互为别名):

    • @RequestParam(value=“username”),注:注解中的value的值一定不要写错,最好从前端页面中复制标签的id,否则会报400错误:错误的请求。
  • required属性:

    • 默认为true,表示方法参数是必需的。如果请求中缺少对应的参数,则会抛出异常。

      • 可以设置为false表示不是必需的,若请求缺少对应参数,则方法的参数为null。

        @RequestMapping("/user/login")
        public String login(
            // 此时,若请求信息中不包含username,也不会报错
            @RequestParam(value="username", required="false")
            String username){
            
            // 返回逻辑视图
            return "ok";
        }
        
  • defaultValue属性:

    • 用来设置形参的默认值,即当没有提供对应的请求参数或者请求参数的值是空字符串""的时候,方法的形参会采用默认值。

      @RequestMapping("/user/login")
      public String login(
          // 此时,若请求信息中不包含username,则username默认值为admin
          @RequestParam(value="username", required="false", defaultValue="admin")
          String username){
          
          // 返回逻辑视图
          return "ok";
      }
      
    • @RequestParam 这个注解是可以省略的,如果方法形参的名字和提交数据时的name相同,则 @RequestParam 可以省略。但是在Spring6+版本以上,需要在pom.xml文件中配置一些信息(这里就不作展开了)。

  • 若是需要获取的参数有很多,用@RequestParam一个一个写就会显得很繁琐,因此有以下方式:

    • 将需要获取的参数封装为一个实体类,如本教程案例中的pojo类中的User类。

      @RequestMapping("/user/login")
      public String login(User user){
          // 底层原理是Java的反射机制
          System.out.println(user);
          // 返回逻辑视图
          return "ok";
      }
      
      • 该User中必须含有对应属性的setter()方法,如参数username,则对应setter方法为setUsername()。

5. @RequestBody

  • @RequestBody主要用来接收前端传递给后端json字符串中的数据的(请求体中的数据的)。

    • 前后端数据交互的方式有很多种,如本案例的表单,还有如JavaScript中的ajax方式(可以异步加载,无刷新更新内容)来进行数据交互,此时可以将数据封装为json格式。

    • 这里我们采用Postman接口测试工具,来向后端发送一个使用json格式的数据

      • 后端代码IndexController.java中

        @RequestMapping("/user/add")
        public String addUser(@RequestBody User user){
            System.out.println(user);
            return "ok";
        }
        
      • Postman中输入如下:

        在这里插入图片描述

    • 使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST等方式进行提交。

    • 当@RequestBody将数据装配到目标类(User.java)时,会根据json字符串中的key来匹配对应实体类的属性,此时会调用实体类中的setter方法进行赋值。

6. @PathVariable

  • 先介绍一种设计风格:RESTFul风格,这只是一种风格,不是一种协议,可以使用XML格式定义。

    • RESTFul是面向资源的,每个资源都会有一个唯一的资源标识符(URI),客户端通过HTTP请求访问这些资源,并使用HTTP方法来执行特定的操作。

    • 传统方式:

      // 发送的请求URL为:http://localhost:8080/springmvc/getUser?id=1
      // 后端获取该参数方法
      @GetMapping("/getUser")
      public String getUser(@RequestParam("id") Integer id){
          System.out.println("要查询的用户id为:" + id);
          // 业务逻辑代码
          return "ok";
      }
      
    • 使用RESTFul风格:

      // 发送的请求URL为:http://localhost:8080/springmvc/getUser/1
      // 此时我们可以看到两种风格的区别,前者数据在参数部分,后者在路径部分
      @GetMapping("/getUser/{id}")
      public String getUserByPath(@PathVariable("id") Integer id){
          System.out.println("要查询的用户id为:" + id);
          // 业务逻辑代码
          return "ok";
      }
      
    • 此时我们可以看到@RequestParam与@PathVariable这俩个注解的区别了:

      • 当我们需要URL中的参数通过路径传参时,使用@PathVariable注解,当使用参数传参时,使用@RequestParam传参。
      • 什么时候路径传参、参数传参呢?建议当URL指向某一具体资源时,会使用路径传参,如访问某个人的博客,https://blogs/{blogId},而筛选某篇文章时,会用https://blogs?state=publish。总的来说,指向具体:路径,筛选过滤资源:参数传参。
    • @PathVariable中的参数也与@RequestParam类似,源码如下:

      @Target({ElementType.PARAMETER})
      @Retention(RetentionPolicy.RUNTIME)
      @Documented
      public @interface PathVariable {
          @AliasFor("name")
          String value() default "";
      
          @AliasFor("value")
          String name() default "";
      
          boolean required() default true;
      }
      

7. @RestController

  • @RestController是@Controller@ResponseBody的组合(@ResponseBody会将java对象直接返回写入到响应体中,一般为JSON数据)。

  • 使用@RestController注解的类会自动被Spring MVC识别为控制器,并将其方法的返回值作为HTTP响应的正文。

  • 将对如下示例进行解析:

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @GetMapping("/list")
        public List<User> listUsers() {
            // 返回用户列表
            // 返回值会被自动序列化为JSON格式
        }
    }
    
    • @RestController这个注解表明UserController类是一个控制器,并且它的所有方法的返回值都将被序列化为JSON(或其它配置的格式),直接作为HTTP响应的正文返回。
  • 什么时候使用@RestController?

    • 在Web应用程序中,前端页面可能需要请求用户列表以展示给用户。

    • 响应的数据是一个java对象,内容较多时,SpringMVC会自动将返回的对象序列化为JSON,简化了数据传输的过程。

      
      

7. @RestController

  • @RestController是@Controller@ResponseBody的组合(@ResponseBody会将java对象直接返回写入到响应体中,一般为JSON数据)。

  • 使用@RestController注解的类会自动被Spring MVC识别为控制器,并将其方法的返回值作为HTTP响应的正文。

  • 将对如下示例进行解析:

    @RestController
    @RequestMapping("/user")
    public class UserController {
    
        @GetMapping("/list")
        public List<User> listUsers() {
            // 返回用户列表
            // 返回值会被自动序列化为JSON格式
        }
    }
    
    • @RestController这个注解表明UserController类是一个控制器,并且它的所有方法的返回值都将被序列化为JSON(或其它配置的格式),直接作为HTTP响应的正文返回。
  • 什么时候使用@RestController?

    • 在Web应用程序中,前端页面可能需要请求用户列表以展示给用户。
    • 响应的数据是一个java对象,内容较多时,SpringMVC会自动将返回的对象序列化为JSON,简化了数据传输的过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悦享未来

你的鼓励必将成为我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值