因为没搞清楚 @RequestBody 和 @ModelAttribute 的区别,我觉得 @ModelAttribute 是 Swagger 的一个注解,结果我明明使用对象接收参数的,结果对象里面都是 null。html
后来把 @ModelAttribute 去掉,发现就能够接收到 json 了。前端
既然遇到了这个问题,那么仍是了解一下这两个注解以及它们的不一样之处吧。java
@RequestBody 注解经常使用来处理 content-type 不是默认的 application/x-www-form-urlcoded 编码的内容,好比说:application/json 或者是 application/xml 等。通常状况下来讲经常使用其来处理 application/json 类型。ajax
如今有以下的 ajax 请求:json
$.ajax({ url:"/login", type:"POST", data:'{"userName":"admin","pwd","admin123"}', content-type:"application/json charset=utf-8", success:function(data){ alert("request success ! "); } });
此时做为后台开发,你能够有两种方式接收参数:session
将 json 字符串中的两个变量分别赋予两个字符串app
@RequestMapping("/login") public void login(@RequestBody String userName, @RequestBody String pwd){ System.out.println(userName + " :" + pwd); }
这种方法我却是用的比较少,通常都是用第二种方法。函数
构造一个 User 类,这个 User 类有以下的字段post
String userName; String pwd;
而后接收方式以下:ui
@RequestMapping("/login") public void login(@RequestBody User user){ System.out.println(user.getUserName + " :" + user.getPwd); }
这样也能够接收参数,并且是最经常使用的。
在一些特殊状况 @RequestBody 也能够用来处理 content-type 类型为 application/x-www-form-urlcoded 的内容,只不过这种方式不是很经常使用,在处理这类请求的时候,@RequestBody 会将处理结果放到一个 MultiValueMap<String, String> 中。
@RequestBody 用于 post 请求,不能用于 get 请求。(某些时候仍是能够用于 GET 请求的,只不过 HTTP 协议不推荐这么作,由于 GET 通常不在 请求体中带上数据,这个和实现有关。)
在 Spring MVC 中,注解 @ModelAttribute 是一个很是经常使用的注解,其功能主要在两方面:
通常开发中,第一种用法居多,第二种用法能够节省 controller 层的一些代码。
@ModelAttribute 注释 void 返回值的方法
@Controller public class HelloWorldController { @ModelAttribute public void populateModel(@RequestParam String abc, Model model) { model.addAttribute("attributeName", abc); } @RequestMapping(value = "/helloWorld") public String helloWorld() { return "helloWorld"; } }
这个例子,在得到请求 /helloWorld 后,populateModel 方法在 helloWorld 方法以前先被调用,它把请求参数(/helloWorld?abc=text)加入到一个名为 attributeName 的 model 属性中,在它执行后 helloWorld 被调用,返回视图名 helloWorld 和 model 已由 @ModelAttribute 方法生产好了。例子中 model 属性名称和 model 属性对象由 model.addAttribute() 实现,不过前提是要在方法中加入一个 Model 类型的参数。
当 URL 或者 post 中不包含次参数时,会报错,其实不须要这个方法,彻底能够把请求的方法写成,这样缺乏此参数也不会出错。
@RequestMapping(value = "/helloWorld") public String helloWorld(String abc) { return "helloWorld"; }
@ModelAttribute 注释返回具体类的方法
@ModelAttribute public Account addAccount(@RequestParam String number) { return accountManager.findAccount(number); }
这种状况,model 属性的名称没有指定,它由返回类型隐含表示,如这个方法返回 Account 类型,那么这个 model 属性的名称是 account。
这个例子中 model 属性名称有返回对象类型隐含表示,model 属性对象就是方法的返回值。它无需要特定的参数。
@ModelAttribute(value="") 注释返回具体类的方法
@Controller public class HelloWorldController { @ModelAttribute("attributeName") public String addAccount(@RequestParam String abc) { return abc; } @RequestMapping(value = "/helloWorld") public String helloWorld() { return "helloWorld"; } }
这个例子中使用 @ModelAttribute 注释的 value 属性,来指定model属性的名称。model属性对象就是方法的返回值。它无需要特定的参数。
@ModelAttribute 和 @RequestMapping 同时注释一个方法
@Controller public class HelloWorldController { @RequestMapping(value = "/helloWorld.do") @ModelAttribute("attributeName") public String helloWorld() { return "hi"; } }
这时这个方法的返回值并非表示一个视图名称,而是 model 属性的值,视图名称由RequestToViewNameTranslator 根据请求 "/helloWorld.do" 转换为逻辑视图 helloWorld。
Model 属性名称由 @ModelAttribute(value="") 指定,至关于在 request 中封装了 key=attributeName,value=hi。
@ModelAttribute 注释一个方法的参数
从model中获取
@Controller public class HelloWorldController { @ModelAttribute("user") public User addAccount() { return new User("jz","123"); } @RequestMapping(value = "/helloWorld") public String helloWorld(@ModelAttribute("user") User user) { user.setUserName("jizhou"); return "helloWorld"; } }
在这个例子里,@ModelAttribute("user") User user 注释方法参数,参数 user 的值来源于 addAccount() 方法中的 model 属性。此时若是方法体没有标注 @SessionAttributes("user"),那么scope 为 request,若是标注了,那么 scope 为 session
从 Form 表单或 URL 参数中获取(实际上,不用此注解也能拿到 user 对象)
@Controller public class HelloWorldController { @RequestMapping(value = "/helloWorld") public String helloWorld(@ModelAttribute User user) { return "helloWorld"; } }
注意这时候这个User类必定要有没有参数的构造函数。
这他妈的,ModelAttribute 这么麻烦。。。
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 配置,转化成参数接收对象或字段。
能够经过required=false或者true来要求@RequestParam配置的前端参数是否必定要传。
若是用@RequestMapping注解的参数是int基本类型,可是required=false,这时若是不传参数值会报错,由于不传值,会赋值为null给int,这个不能够 。
@RequestParam 和 @PathVariable 都可以完成相似的功能:由于本质上,它们都是用户的输入,只不过输入的部分不一样,一个在URL路径部分,另外一个在参数部分。
使用这个注解前提是在 @RequestMapping 中必须指定模板。
https://www.cnblogs.com/qiankun-site/p/5774300.html
https://blog.csdn.net/zz210891470/article/details/59719251