一、@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