• Spring @RequestParam、@RequestBody和@ModelAttribute区别


    一、@RequestParam
    GET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上
    1. @RequestParam(org.springframework.web.bind.annotation.RequestParam)用于将指定的请求参数赋值给方法中的形参。
    例:
    (1) get请求:

    url请求:http://localhost:8080/WxProgram/findAllBookByTag?tagId=1&pageIndex=3

    userTest.jsp

    <form action="/WxProgram/json/requestParamTest" method="get">
        requestParam Test<br>
        用户名:<input type="text" name="username"><br>
        用户昵称:<input type="text" name="usernick"><br>
        <input type="submit" value="提交">
    </form>

    UserController.java

        @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
        public String requestParamTest(@RequestParam(value="username") String userName, @RequestParam(value="usernick") String userNick){
            System.out.println("requestParam Test");
            System.out.println("username: " + userName);
            System.out.println("usernick: " + userNick);
            return "hello";
        }

    上述代码会将请求中的username参数的值赋给username变量。

    等价于:

        @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
        public String requestParamTest(String username, HttpServletRequest request){
            System.out.println("requestParam Test");
            System.out.println("username: " + username);
            String usernick = request.getParameter("usernick");
            System.out.println("usernick: " + usernick);
            return "hello";
        }

    也可以不使用@RequestParam,直接接收,此时要求controller方法中的参数名称要跟form中name名称一致

        @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
        public String requestParamTest(String username, String usernick){
            System.out.println("requestParam Test");
            System.out.println("username: " + username);
            System.out.println("usernick: " + usernick);
            return "hello";
        }

    总结:

    接收请求参数的方式:

    @RequestParam(value="username") String userName, @RequestParam(value="usernick") String userNick //value中的参数名称要跟name中参数名称一致
    String username, String usernick// 此时要参数名称一致
    HttpServletRequest request //request.getParameter("usernick")

    (2) post请求:
    跟get请求格式一样,只是把方法中的get换成post

    @RequestParam
    用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容。提交方式为get或post。(Http协议中,如果不指定Content-Type,则默认传递的参数就是application/x-www-form-urlencoded类型)

    RequestParam实质是将Request.getParameter() 中的Key-Value参数Map利用Spring的转化机制ConversionService配置,转化成参数接收对象或字段。

    get方式中query String的值,和post方式中body data的值都会被Servlet接受到并转化到Request.getParameter()参数集中,所以@RequestParam可以获取的到。

    二. @RequestBody

    @RequestBody注解可以接收json格式的数据,并将其转换成对应的数据类型。

    1. @RequestBody接收一个对象
    url请求:http://localhost:8080/WxProgram/findBookByName

    @RequestMapping(value="/findBookByName", method = RequestMethod.POST)
    @ResponseBody
    public DbBook findBookByName(@RequestBody DbBook book){
        System.out.println("book: " + book.toString());
        System.out.println("book name: " + book.getTitle());
        String bookName = book.getTitle();
        DbBook book = wxService.findBookByName(bookName);    
        return book;
    }

    2. @RequestBody接收不同的字符串

    (1)前台界面,这里以小程序为例

    wx.request({
          url: host.host + `/WxProgram/deleteBookById`,
          method: 'POST',
          data: {
            nick: this.data.userInfo.nickName,
            bookIds: bookIds
          },
          success: (res) => {
            console.log(res);
            this.getCollectionListFn();
          },
          fail: (err) => {
            console.log(err);
          }
        })

    (2)controller

    @RequestMapping(value="/deleteBookById",method=RequestMethod.POST)
    @ResponseBody
    public void deleteBookById(@RequestBody Map<String, String> map){
        String bookIds = map.get("bookIds");
        String nick = map.get("nick");
        String[] idArray = bookIds.split(",");
        Integer userId = wxService.findIdByNick(nick);
        for(String id : idArray){
            Integer bookid = Integer.parseInt(id);
            System.out.println("bookid: " + bookid);
            wxService.removeBookById(bookid, userId);
        }
    }

    @RequestBody
    处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据。

    GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。
    POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

    @RequestBody用于post请求,不能用于get请求

    这里涉及到使用@RequestBody接收不同的对象
    1. 创建一个新的entity,将两个entity都进去。这是最简单的,但是不够“优雅”。
    2. 用Map<String, Object>接受request body,自己反序列化到各个entity中。
    3. 类似方法2,不过更为generic,实现自己的HandlerMethodArgumentResolver。参考这里 

    三、@ModelAttribute

    @ModelAttribute注解类型将参数绑定到Model对象

    1. userTest.jsp

    <form action="/WxProgram/json/modelAttributeTest" method="post">
        modelAttribute Test<br>
        用户id:<input type="text" name="userId"><br>
        用户名:<input type="text" name="userName"><br>
        用户密码:<input type="password" name="userPwd"><br>
        <input type="submit" value="提交"><br>
    </form>

    name的属性值要跟User的属性相对应。

    2. UserController.java

    @RequestMapping(value="/modelAttributeTest", method = RequestMethod.POST)
        public String modelAttributeTest(@ModelAttribute User user){
            System.out.println("modelAttribute Test");
            System.out.println("userid: " + user.getUserId());
            System.out.println("username: " + user.getUserName());
            System.out.println("userpwd: " + user.getUserPwd());
            return "hello";
        }

    3. User.java

    public class User {
        private Integer userId;
        private String userName;
        private String userPwd;
        
        public User(){
            super();
        }
            //setter and getter      
    }

    当前台界面使用GET或POST方式提交数据时,数据编码格式由请求头的ContentType指定。分为以下几种情况:
    1. application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute可以处理,@RequestBody也可以处理。
    2. multipart/form-data,@RequestBody不能处理这种格式的数据。(form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。)
    3. application/json、application/xml等格式的数据,必须使用@RequestBody来处理。

    参考:

    @RequestBody和@RequestParam区别 

    https://segmentfault.com/q/1010000009017635

    https://www.cnblogs.com/zeroingToOne/p/8992746.html

  • 相关阅读:
    python 中的[::-1]
    python 闭包
    elastic
    文件上传进度条修改
    python decorator的理解
    同方爬虫--面试题
    js typeof
    浅谈软件项目实施
    数独·唯一性技巧(Uniqueness)-1
    数独二
  • 原文地址:https://www.cnblogs.com/panchanggui/p/10762977.html
Copyright © 2020-2023  润新知