zoukankan      html  css  js  c++  java
  • @RequestParam、@RequestBody、@ResponseBody和@PathVariable的使用与区别

    目录

    一、@RequestParam 注解

    1.1 解释说明

    1.2 代码示例

    1.3 总结

    二、@RequestBody 注解

    2.1 解释说明

    2.2 代码示例

    2.3 总结

    三、@ResponseBody 注解

    3.1 解释说明

    3.2 代码示例

    3.3 总结

    四、@PathVariable 注解

    4.1 解释说明

    4.2 代码示例

    4.3 总结


    一、@RequestParam 注解

    1.1 解释说明

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

    @RequestParam可以接受简单类型的属性,也可以接受对象类型。(实质是将Request.getParameter() 中的Key-Value参数Map利用Spring的转化机制ConversionService配置,转化成参数接收对象或字段。)

    知识点:在Content-Type: application/x-www-form-urlencoded的请求中,get 方式中queryString的值,和post方式中body data 的值都会被Servlet接受到并转化到Request.getParameter()参数集中,所以@RequestParam可以获取的到。

    1.2 代码示例

    GET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上

    @RequestParam(org.springframework.web.bind.annotation.RequestParam)用于将指定的请求参数赋值给方法中的形参。

    <form action="/user/requestParamTest" method="get">
        requestParam Test<br>
        用户名字:<input type="text" name="username"><br>
        用户昵称:<input type="text" name="nickname"><br>
        <input type="submit" value="提交">
    </form>
    @RequestMapping(value="/requestParamTest", method = RequestMethod.GET)
    public String requestParamTest(@RequestParam(value="username") String userName, @RequestParam(value="nickname") String nickName){
        System.out.println("requestParam Test");
        System.out.println("username: " + userName);
        System.out.println("nickname: " + nickName);
        return "hello";
    }


    上述代码会将请求中的username和nickname参数的值分别赋给userName变量和nickName变量。请求中的参数username和nickname必须与@RequestParam(value="xxxx")的value值保持一致。

    等价于:

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

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

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

    1.3 总结

    接收请求参数的方式:

    方式一:用@RequestParam接受。(@RequestParam(value="username") String userName, @RequestParam(value="nickname") String nickName) //value中的参数名称要跟请求参数Key的名称一致
    方式二:不用注解,直接接受。(String username, String nickname) // 此时要参数名称一致
    方式三:用HttpServletRequest接受。(HttpServletRequest request) //request.getParameter("username")

    二、@RequestBody 注解

    2.1 解释说明

    @RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。

    作用:

    1) 该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上;
    2) 再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

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

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

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

    2.2 代码示例

    @RequestBody接收一个对象

    @ApiOperation("外设SDK按照参数查询可展示的广告信息")
    @PostMapping("/openapi/advert/getOutAdvertList")
    public CommResponse<?> getOutAdvertList(@RequestBody OutAdvertRequestParam outAdvertRequestParam);

    (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);
        }
    }

    2.3 总结

    在GET请求中,不能使用@RequestBody
    在POST请求,可以使用@RequestBody@RequestParam,但是如果使用@RequestBody,对于参数转化的配置必须统一。
    举个例子,在SpringMVC配置了HttpMessageConverters处理栈中,指定json转化的格式,如Date转成‘yyyy-MM-dd’,则参数接收对象包含的字段如果是Date类型,就只能让客户端传递年月日的格式,不能传时分秒。因为不同的接口,它的参数可能对时间参数有不同的格式要求,所以这样做会让客户端调用同事对参数的格式有点困惑,所以说扩展性不高。

    如果使用@RequestParam来接受参数,可以在接受参数的model中设置@DateFormat指定所需要接受时间参数的格式。

    另外,使用@RequestBody接受的参数是不会被Servlet转化统一放在request对象的Param参数集中,@RequestParam是可以的。

    综上所述,一般情况下,推荐使用@RequestParam注解来接受Http请求参数。


    三、@ResponseBody 注解

    3.1 解释说明

    @Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用,通常是在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。
    作用:
    该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
    使用时机:
    返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;

    3.2 代码示例

    当页面发出异步请求:

    function login() {
        var datas = '{"username":"' + $('#username').val() + '","userid":"' + $('#userid').val() + '","status":"' + $('#status').val() + '"}';
        $.ajax({
            type : 'POST',
            contentType : 'application/json',
            url : "${pageContext.request.contextPath}/user/login",
            processData : false,
            dataType : 'json',
            data : datas,
            success : function(data) {
                alert("userid: " + data.userid + "username: " + data.username + "status: "+ data.status);
            },
            error : function(XMLHttpRequest, textStatus, errorThrown) {
                alert("出现异常,异常信息:"+textStatus,"error");
            }
        });
    };
    @RequestMapping(value = "user/login")
    @ResponseBody
    // 将ajax(datas)发出的请求写入 User 对象中,返回json对象响应回去
    public User login(User user) {   
        User user = new User();
        user .setUserid(1);
        user .setUsername("MrF");
        user .setStatus("1");
        return user ;
    }

    异步获取 json 数据,加上 @Responsebody 注解后,就会直接返回 json 数据。

    3.3 总结

    当前端页面需要返回 json 数据时,可以使用@ResponseBody加到方法上。

    四、@PathVariable 注解

    4.1 解释说明

    @PathVariable 注解,其用来获取请求路径(url )中的动态参数。

    在默认的情况下,Spring会对@PathVariable注解的变量进行自动赋值,当然你也可以指定@PathVariable使用哪一个URL中的变量。

    4.2 代码示例

    (1)页面发出请求:

    function login() {
        var url = "${pageContext.request.contextPath}/person/login/";
        var query = $('#id').val() + '/' + $('#name').val() + '/' + $('#status').val();
        url += query;
        $.get(url, function(data) {
            alert("id: " + data.id + "name: " + data.name + "status: "
                    + data.status);
        });
    }

    (2)Controller层

    /**
    * @RequestMapping(value = "user/login/{id}/{name}/{status}") 中的 {id}/{name}/{status}
    * 与 @PathVariable int id、@PathVariable String name、@PathVariable boolean status
    * 一一对应,按名匹配。
    */
    @RequestMapping(value = "user/login/{id}/{name}/{status}")
    @ResponseBody
    //@PathVariable注解下的数据类型均可用
    public User login(@PathVariable int id, @PathVariable String name, @PathVariable boolean status) {
    //返回一个User对象响应ajax的请求
        return new User(id, name, status);
    }

    这种情况下,Spring能够根据名字自动赋值对应的函数参数值,当然也可以在@PathVariable中显示地表明具体的URL变量值。

    在默认情况下,@PathVariable注解的参数可以是一些基本的简单类型:int,long,Date,String等,Spring能根据URL变量的具体值以及函数参数的类型来进行转换。

    (3) 匹配正则表达式

    很多时候,需要对URL变量进行更加精确的定义,例如-用户名只可能包含小写字母,数字,下划线,我们希望:

    /user/fpc是一个合法的URL
    /user/#$$$则不是一个合法的URL

    除了简单地定义{username}变量,还可以定义正则表达式进行更精确的控制,定义语法是{变量名:正则表达式}[a-zA-Z0-9_]+是一个正则表达式,表示只能包含小写字母,大写字母,数字,下划线。如此设置URL变量规则后,不合法的URL则不会被处理,直接由SpringMVC框架返回404Not Found。

    @RequestMapping("/user/{username:[a-zA-Z0-9_]+}/blog/{blogId}")

    4.3 总结

    (1) 在@RequestMapping注解中定义URL变量规则;
    (2) 在@RequestMapping注解方法中获取URL变量-@PathVariable;
    (3) @PathVariable指定URL变量名;
    (4) 定义多个URL变量;
    (5) 用正则表达式精确定义URL变量;

    【参考资料】
    1、可参考SpringBoot-@PathVariable:https://www.cnblogs.com/williamjie/p/9139548.html

  • 相关阅读:
    Block编程
    自己写Web服务器(续)
    C# 2.0对现有语法的改进
    使用CDN
    优化网站设计(一):减少请求数
    MongoDB Shell的使用
    memcache 和appfabric
    go语言中几个有趣的特性以及对go的看法
    bpm流程平台
    Socket编程 (异步通讯) (Tcp,Udp)Part2
  • 原文地址:https://www.cnblogs.com/no8g/p/13415527.html
Copyright © 2011-2022 走看看