Spring MVC @ControllerAdvice Annotation Example
June 28, 2019
@ControllerAdvice annotation is a specialization of @Component. The classes annotated with @ControllerAdvice are auto detected by classpath scanning. The use of @ControllerAdvice is advising all or selected controllers for @ExceptionHandler, @InitBinder and @ModelAttribute. What we have to do is create a class annotated with @ControllerAdvice and create required method which will be annotated with @ExceptionHandler for global exception handling, @InitBinder for global init binding and @ModelAttribute for global model attributes addition. Whenever a request comes to controller and its method with @RequestMapping and if there is no locally defined @ExceptionHandler, @InitBinder and @ModelAttribute, the globally defined class annotated with @ControllerAdvice is served.
@ControllerAdvice has attributes annotations, assignableTypes and basePackages . To use @ControllerAdvice, we should use @EnableWebMvc annotation in our java config.
Create a class Annotated with @ControllerAdvice
Find the sample class annotated with @ControllerAdvice. Here we are declaring methods for @ExceptionHandler, @InitBinder and @ModelAttribute to understand how to use it. We are using basePackages attribute of @ControllerAdvice to limit the controller classes. In this attribute we can define the array of base packages of controllers which can be used by @ControllerAdvice class, if not used basePackages attribute, then all controllers in classpath annotated with @Controller will be served by our @ControllerAdvice class.GlobalControllerAdvice.java
@ControllerAdvice(basePackages = {"com.concretepage.controller"} ) public class GlobalControllerAdvice { @InitBinder public void dataBinding(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, "dob", new CustomDateEditor(dateFormat, true)); } @ModelAttribute public void globalAttributes(Model model) { model.addAttribute("msg", "Welcome to My World!"); } @ExceptionHandler(FileNotFoundException.class) public ModelAndView myError(Exception exception) { ModelAndView mav = new ModelAndView(); mav.addObject("exception", exception); mav.setViewName("error"); return mav; } }
Create Controller
Find the controller with a @RequestMapping method for the demo. Here we have also defined a controller specific @InitBinder method.MyWorldController.java
@Controller @RequestMapping("/myworld") public class MyWorldController { @Autowired private UserValidator userValidator; @RequestMapping(value="signup", method = RequestMethod.GET) public ModelAndView user(){ return new ModelAndView("user","user",new User()); } @InitBinder public void dataBinding(WebDataBinder binder) { binder.addValidators(userValidator); } @RequestMapping(value="save", method = RequestMethod.POST) public String createUser(@ModelAttribute("user") @Valid User user,BindingResult result, ModelMap model) throws FileNotFoundException { if(result.hasErrors()) { return "user"; } if(user.getName().equals("exception")) { throw new FileNotFoundException("Error found."); } System.out.println("Name:"+ user.getName()); System.out.println("Date of Birth:"+ user.getDob()); return "success"; } }