Tuesday, January 8, 2013

Spring 3.0 MVC Validation and Exception Handling


Domain Class:

Define contraints in domain class. You can define your own constraints.
 
 import javax.validation.constraints.NotNull;  
 import javax.validation.constraints.Size;  
 public class Response {  
   private BigInteger id;  
   @NotNull  
   private BigInteger itemId;  
   @Size(min = 1, max = 14)  
   private String response;  
 }  

Controller Class:

@Valid annotiation on incoming parameter to trigger validation.
@ExceptionHandler to handle different type of exceptions.

 
@Controller
public class ResponseController {
    public @ResponseBody Response postResponse(
        @Valid @RequestBody ItemResponse itemResponse){

    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public String handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();
        List errors = bindingResult.getFieldErrors();
        StringBuffer customMessage = new StringBuffer();
        for (FieldError error : errors ) {
            customMessage.append(error.getObjectName() +"." + error.getField() +" "+ error.getDefaultMessage()+"\n");
        }        
        return customMessage.toString();
    }

    @ExceptionHandler(IOException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public ModelAndView handleIOException(MethodArgumentNotValidException ex) {
   …. 
    }
}

Spring Configuration:

Following are example configuration for different types of Exception Handler.

   <!-- Annotation Based ExceptionHandler -->  
   <beans:bean  
     class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">  
     <beans:property name="order" value="1" />  
   </beans:bean>  
   
   <!-- SimpleMapping ExceptionHandler -->  
   <beans:bean  
   class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
     <beans:property name="exceptionMappings">  
       <beans:props>  
         <beans:prop  
           key="org.springframework.web.bind.MethodArgumentNotValidException">validationError</beans:prop>  
         <beans:prop key="java.lang.IOException">ioerror</beans:prop>  
       </beans:props>  
     </beans:property>  
     <beans:property name="statusCodes">  
       <beans:props>  
         <beans:prop key="ioerror">403</beans:prop>  
         <beans:prop key="validationError">406</beans:prop>  
       </beans:props>  
     </beans:property>  
     <beans:property name="defaultErrorView" value="error" />  
     <beans:property name="order" value="2" />  
   </beans:bean>  

   <!-- Default ExceptionHandler -->  
   <beans:bean  
     class="org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver">  
     <beans:property name="order" value="3" />  
   </beans:bean>  


2 comments:

  1. Wow,

    Hi feier, very nice post, but don't understand how to use ResponseController... i have extends my controllers of ResponseController, or i have declaration/definition this controller in spring-context.xml? how to use that solution?

    Thanks, waiting response!

    ReplyDelete
  2. Hi feier,

    Nice post. But are you sure the @Valid @RequestBody ItemResponse itemResponse can work in Spring 3.0? Seems it's supported since Spring3.1.
    And now I encountered an issue of this can not work in 3.0. Can you please help confirm?

    Thanks,
    Bobby

    ReplyDelete