Spring 开发随笔

@RequestBody 注解抛出异常

问题描述:使用 @RequestBody 注解时,抛出异常信息 “Required request body is missing”

采用 SSM 框架,前端将参数传递给后端,SpringMVC 可以通过注解 @RequestBody 将传递参数绑定在 Controller 的方法参数中。此时必须注意,当请求方法声明为 GET 和 DELETE 的时候,HTTP 请求规范里规定是不会有 RequestBody 的,只有请求方法声明为 POST 和 PUT 的时候才有,因此 @RequestBody 不适用于 GET 与 DELETE 方法。还有如果请求方法声明为 GET、DELETE,那么 SpringMVC 可以直接将传递参数绑定在方法的参数中,如果请求方法声明为 POST、PUT,则必须使用注解 @RequestBody 修饰 Controller 中的方法参数,否则无法获取前端传递过来的参数值。正确的使用方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@Controller
@RequestMapping("/user/api")
public class UserApiController {

@Autowired
private UserApiService userApiService;

@ResponseBody
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
public RequestResult<UserApiVo> getById(@PathVariable("id") int id) {
return userApiService.get(id);
}

@ResponseBody
@RequestMapping(value = "/query", method = RequestMethod.GET)
public RequestResult<Page> query(Page page) {
return userApiService.query(page);
}

@ResponseBody
@RequestMapping(value = "/add", method = RequestMethod.POST)
public RequestResult add(@RequestBody @Valid UserApiVo vo) {
return userApiService.add(vo);
}

@ResponseBody
@RequestMapping(value = ("/update"), method = RequestMethod.POST)
public RequestResult update(@RequestBody @Valid UserApiVo vo) {
return userApiService.update(vo);
}

@ResponseBody
@RequestMapping(value = "/delete/{id}", method = RequestMethod.DELETE)
public RequestResult delete(@PathVariable("id") int id) {
return userApiService.delete(id);
}

}

@Autowired 和 @Resource 的区别

在 Spring 中,@Autowired@Resource 注解都可以用来实现依赖注入,两者的不同点如下:

  • 来源不同
    • @Autowired 是 Spring 提供的注解
    • @Resource 是 Java EE 提供的注解
  • 依赖查找顺序不同
    • @Autowired 会先根据类型查找,如果根据类型查找不到或者查找到多个 Bean,则会根据名称进行查找
    • @Resource 会先根据名称查找,如果根据名称查找不到,则会根据类型进行查找,如果最后查找不到,则会报错
  • 支持的参数不同
    • @Autowired 只支持 required 参数
    • @Resource 支持 nametype 等 7 个参数
  • 依赖注入的方式不同
    • @Autowired 支持构造方法注入、属性注入、Setter 注入
    • @Resource 只支持属性注入和 Setter 注入
  • 编译器提示不同
    • 在 IntelliJ IDEA 中,@Autowired 提供了更好的 IDE 提示
    • 在 IntelliJ IDEA 中,@Resource 的 IDE 提示相对较弱
  • 使用细节不同
    • @Autowired 可以配合 @Qualifier 一起使用,用于指定具体要注入的 Bean 的名称
    • @Autowired 查找到多个符合类型的 Bean 时,可以使用 @Primary 修饰特定的 Bean,这样该 Bean 就会被优先用来注入
    • 在默认情况下,@Autowired 要求依赖对象必须存在,如果需要允许 Null 值,可以设置它的 required 属性为 false

总结

  • 更多内容建议阅读 《@Autowired 和 @Resource 的区别》
  • 一般来说,@Autowired 更常用一些,因为它支持根据类型和名称进行自动装配,并且可以结合 @Qualifier 注解使用,而 @Resource 注解主要用于 Java EE 环境,例如 EJB 容。