Spring MVC @ControllerAdvice Annotation Example

By Arvind Rai, October 11, 2023
Spring @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 annotations. What we have to do is, create a class annotated with @ControllerAdvice and create a 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 hits the controller for any @RequestMapping and if there is no locally defined exception handler, the globally defined class annotated with @ControllerAdvice is served.
@ControllerAdvice has attributes as annotations, assignableTypes and basePackages . To work with @ControllerAdvice, we need to use @EnableWebMvc annotation in our JavaConfig.

Using @ControllerAdvice

Find the sample class using @ControllerAdvice annotation. 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. This attribute can be assigned with the array of base packages of controllers which can be used by @ControllerAdvice class, if basePackages attribute is not used, 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;
	}
} 
Find the page to display error messages.
error.jsp
<html>
<head>
<title> Global Error </title>
</head>
    <body>
    <h1>${exception.message}</h1>
    </body>
</html> 

Create Controller

Find the controller with a @RequestMapping method. 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";
	}	
} 

1. The exception FileNotFoundException thrown in the controller is not being handled locally, so it will be handled by global exception handling class that is annotated by @ControllerAdvice.
2. For the date validation, we have no local WebDataBinder configuration, it will be handled by global @InitBinder method.
3. @ModelAttribute for "msg" key is not added in the controller locally. So the method annotated with @ModelAttribute in the GlobalControllerAdvice class is used.

Download Complete Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us