赞
踩
使用场景:从request中取对应的属性值。 注意:属性和参数是不同的。
参数(parameter)和属性(Attribute)的区别:
参数是需要用户或者浏览器传,属性是我们拦截请求写入或者修改的。比如:httpServletRequest.setAttribute(name, value))
如果我们想在controller层中获取绑定属性值到一个参数,此时就可以使用@RequestAttribute,
具体了解参数(parameter)和属性(Attribute)的区别参考下文:
我们一般前后端分离开发每次请求都会携带一些固定的参数,例如: 租户id,坐席 id,我们会将这些固定参数放在 header 中,这时我们就可以使用过滤器来拦截请求,然后将取到的参数可以放到 request 或者 session 作用域中,在 controller 中我们就可以使用 @RequestAttribute 或者 @SessionAttribute 注解来获取值
@RequestAttribute注解的参数在项目里是自己解析出来的,并不是前端传递的。
具体一点,在项目里的拦截器里会对Token信息进行解析,解析出来的参数重新放在请求里(用httpServletRequest.setAttribute(name, value)),后边接口接收参数时就用这个注解。
接下来这句话很重要:@RequestAttribute只负责从request里面取属性值,至于你什么时候往里放值,是有多种方式的可以达到的:
1、@ModelAttribute注解预存
2、HandlerInterceptor拦截器中预存
3、请求转发带过来
扩展
在写http接口的时候,发现接口参数有两种注解,一种是@RequestAttribute,一种是@Requestparam,自己刚开始没明白区别,用postman调试的时候一直报错,后来才发现这个问题。
@RequestAttribute注解的参数在项目里是自己解析出来的,并不是前端传递的。具体一点,在项目里的拦截器里会对Token信息进行解析,解析出来的参数重新放在请求里(用httpServletRequest.setAttribute(name, value)),后边接口接收参数时就用这个注解。
@RequestParam注解则表示这个参数是通过前端传递过来的,如果请求里没有这个参数,则会报错400 Bad Request。这个注解用来解析请求路径里的参数(get请求)或者post请求中form表单格式的请求参数;
@RequestBody注解用来接收POST请求BODY里的参数,格式为JSON格式。
用例:
- @Controller
- public class RequestController {
-
- @GetMapping("/goto")
- public String goToPage(HttpServletRequest request){
-
- request.setAttribute("msg","成功了...");
- request.setAttribute("code",200);
- return "forward:/success"; //转发到 /success请求
- }
-
- @GetMapping("/params")
- public String testParam(Map<String,Object> map,
- Model model,
- HttpServletRequest request,
- HttpServletResponse response){
- map.put("hello","world666");
- model.addAttribute("world","hello666");
- request.setAttribute("message","HelloWorld");
-
- Cookie cookie = new Cookie("c1","v1");
- response.addCookie(cookie);
- return "forward:/success";
- }
-
- ///<-----------------主角@RequestAttribute在这个方法
- @ResponseBody
- @GetMapping("/success")
- public Map success(@RequestAttribute(value = "msg",required = false) String msg,
- @RequestAttribute(value = "code",required = false)Integer code,
- HttpServletRequest request){
- Object msg1 = request.getAttribute("msg");
-
- Map<String,Object> map = new HashMap<>();
- Object hello = request.getAttribute("hello");
- Object world = request.getAttribute("world");
- Object message = request.getAttribute("message");
-
- map.put("reqMethod_msg",msg1);
- map.put("annotation_msg",msg);
- map.put("hello",hello);
- map.put("world",world);
- map.put("message",message);
-
- return map;
- }
- }
注解@RequestBody接收的参数是来自requestBody中,即请求体。
一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。通常用于接收POST、DELETE等类型的请求数据。
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
注:
1、一个请求,只有一个RequestBody;一个请求,可以有多个RequestParam。
2、在GET请求中,不能使用@RequestBody。
当同时使用@RequestParam()和@RequestBody可以同时使用时,原SpringMVC接收参数的机制不变,只不过RequestParam接收的是key-value里面的参数,所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收,而RequestBody 接收的是请求体里面的数据:
如果参数时放在请求体中,application/json传入后台的话,那么后台要用@RequestBody才能接收到;如果不是放在请求体中的话,那么后台接收前台传过来的参数时,要用@RequestParam来接收,或则形参前 什么也不写也能接收。
如果参数前写了@RequestParam(xxx),那么前端必须有对应的xxx名字才行(不管其是否有值,当然可以通过设置该注解的required属性来调节是否必须传),如果没有xxx名的话,那么请求会出错,报400。
如果参数前不写@RequestParam(xxx)的话,那么就前端可以有可以没有对应的xxx名字才行,如果有xxx名的话,那么就会自动匹配;没有的话,请求也能正确发送。
这里与feign消费服务时不同;feign消费服务时,如果参数前什么也不写,那么会被默认是@RequestBody的。
如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:
后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为),这一条我会在下面详细分析,其他的都可简单略过,但是本文末的核心逻辑代码以及几个结论一定要看! 实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。
json字符串中,如果value为""的话,后端对应属性如果是String类型的,那么接受到的就是"",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。
json字符串中,如果value为null的话,后端对应收到的就是null。
如果某个参数没有value的话,在传json字符串给后端时,要么干脆就不把该字段写到json字符串中;要么写value时, 必须有值,null 或""都行。千万不能有类似 "name":, 这样的写法。
声明:根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析。
下面介绍的是最常用的:前端以Content-Type 为application/json,传递json字符串数据;后端以@RequestBody模型接收数据的情况。
Http传递请求体信息,最终会被封装进com.fasterxml.jackson.core.json.UTF8StreamJsonParser中(提示:Spring采用CharacterEncodingFilter设置了默认编码为UTF-8),然后在public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable中,通过 public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException方法进行解析。
引用链接:https://blog.csdn.net/m0_37587418/article/details/125614343
引用链接:https://blog.csdn.net/weixin_46058921/article/details/127794325
引用链接:https://blog.csdn.net/justry_deng/article/details/80972817/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。