@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

发布了146 篇原创文章 · 获赞 221 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_44299027/article/details/104816287