使用@Valid @RequestBody 的用意在于抛出notvalid的异常

Different ways of validating @RequestBody in Spring MVC 3.2 with @Valid annotation

In spring MVC the @RequestBody annotation indicates a method parameter should be bound to a body of the request. @RequestBody parameter can treated as any other parameter in a@RequestMapping method and therefore it can also be validated by a standard validation mechanism. In this post I will show 2 ways of validating the @RequestBody parameter in your Spring MVC application.

In my sample application I want to create a new Task with not blank name and description. In order to do it I create an API endpoint that supports POST method and accepts Task as JSON.

Tip: To bootstrap the application I used: spring-mvc-quickstart-archetype .

Let's start with the task:


   
   
[java] view plain copy
  1. public class Task {  
  2.   
  3.     @NotBlank(message = "Task name must not be blank!")  
  4.     private String name;  
  5.   
  6.     @NotBlank(message = "Task description must not be blank!")  
  7.     private String description;  
  8.   
  9.     public Task() {  
  10.     }  
  11.   
  12.     public Task(String name, String description) {  
  13.         this.name = name;  
  14.         this.description = description;  
  15.     }  
  16.   
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.   
  21.     public void setName(String name) {  
  22.         this.name = name;  
  23.     }  
  24.   
  25.     public String getDescription() {  
  26.         return description;  
  27.     }  
  28.   
  29.     public void setDescription(String description) {  
  30.         this.description = description;  
  31.     }  
  32.   
  33. }  
To handle the task we need a @Controller:

   
   
[java] view plain copy
  1. @Controller  
  2. @RequestMapping(value = "task")  
  3. public class TaskController {  
  4.   
  5.     @RequestMapping(value = "", method = RequestMethod.POST)  
  6.     @ResponseBody  
  7.     public Task post(Task task) {  
  8.         // create a task     
  9.     }  
  10. }  
The next thing we need to do is the validation. So let's do it.

Validation with @ExceptionHandler

As of Spring 3.1 the @RequestBody method argument can be annotated with @Valid or @Validated annotation to invoke automatic validation. In such a case Spring automatically performs the validation and in case of error MethodArgumentNotValidException is thrown. Optional @ExceptionHandler method may be easily created to add custom behavior for handling this type of exception. MethodArgumentNotValidException holds both the parameter that failed the validation and the result of validation. Now, we can easily extract error messages and return it in an error object as JSON.


   
   
[java] view plain copy
  1. @Controller  
  2. @RequestMapping(value = "task")  
  3. public class TaskController {  
  4.   
  5.     @RequestMapping(value = "", method = RequestMethod.POST)  
  6.     @ResponseBody  
  7.     public Task post(@Valid @RequestBody Task task) {         
  8.         // in case of a validation error, MethodArgumentNotValidException will be thrown.  
  9.     }  
  10.   
  11.     @ExceptionHandler  
  12.     @ResponseBody  
  13.     @ResponseStatus(value = HttpStatus.BAD_REQUEST)  
  14.     public Error handleException(MethodArgumentNotValidException exception) {  
  15.         return new ApiErrors(exception.getBindingResult());  
  16.     }  
  17.   
  18. }  

Exception handler method does not need to be located in the same controller class. It can be a global handler for all you API calls.

Validation with Errors/BindingResult object

As of Spring 3.2 @RequestBody method argument may be followed by Errors object, hence allowing handling of validation errors in the same @RequestMapping. Let's look at the code:


   
   
[java] view plain copy
  1. @Controller  
  2. @RequestMapping(value = "task")  
  3. public class TaskController {  
  4.   
  5.     @RequestMapping(value = "", method = RequestMethod.POST)  
  6.     @ResponseBody  
  7.     public ResponseEntity post(@Valid @RequestBody Task task, Errors errors) {  
  8.         if (errors.hasErrors()) {  
  9.             return new ResponseEntity(new ApiErrors(errors), HttpStatus.BAD_REQUEST);  
  10.         }  
  11.         return new ResponseEntity(task.save(), HttpStatus.CREATED);  
  12.     }  
  13. }  

Both approaches produce the same result in the above example. Which is better? I don't know yet. And do you?

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值