In spring 3.2, @ ControllerAdvice annotation is added,
It can be used to define @ ExceptionHandler, @ InitBinder, @ ModelAttribute and apply to all @ RequestMapping.
Reference resources: @Controlleradvise documentation
1, Introduction
Create mycontrolleradvise and add the @ controlleradvise annotation.
import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; /** * controller Enhancer * @author sam * @since 2017/7/17 */ @ControllerAdvice public class MyControllerAdvice { /** * Apply to all @ RequestMapping annotation methods and initialize the data binder before execution * @param binder */ @InitBinder public void initBinder(WebDataBinder binder) {} /** * Bind the value to the Model so that the global @ RequestMapping can get the value * @param model */ @ModelAttribute public void addAttributes(Model model) { model.addAttribute("author", "Magical Sam"); } /** * Global exception capture processing * @param ex * @return */ @ResponseBody @ExceptionHandler(value = Exception.class) public Map errorHandler(Exception ex) { Map map = new HashMap(); map.put("code", 100); map.put("msg", ex.getMessage()); return map; } }
After starting the application, the methods annotated by @ ExceptionHandler, @ InitBinder, @ ModelAttribute will all act on the methods annotated by @ RequestMapping.
@ModelAttribute: the value set on the Model can be obtained through ModelMap for all methods annotated by @ RequestMapping
As follows:
@RequestMapping("/home") public String home(ModelMap modelMap) { System.out.println(modelMap.get("author")); } //Or through@ModelAttribute Obtain @RequestMapping("/home") public String home(@ModelAttribute("author") String author) { System.out.println(author); }
@The exception handler intercepts the exception. We can use this annotation to implement custom exception handling.
Where, the value configured by @ ExceptionHandler specifies the type of exception to be intercepted, which intercepts Exception.class.
2, Custom exception handling (Global exception handling)
By default, spring boot will map to / error for exception handling, but the prompt is not very friendly. Please customize exception handling below to provide a friendly display.
1. Write a custom exception class:
public class MyException extends RuntimeException { public MyException(String code, String msg) { this.code = code; this.msg = msg; } private String code; private String msg; // getter & setter }
Note: spring only rolls back transactions for RuntimeException exceptions.
2. Write global exception handling class
import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; /** * controller Enhancer * @author sam * @since 2017/7/17 */ @ControllerAdvice public class MyControllerAdvice { /** * Global exception capture processing * @param ex * @return */ @ResponseBody @ExceptionHandler(value = Exception.class) public Map errorHandler(Exception ex) { Map map = new HashMap(); map.put("code", 100); map.put("msg", ex.getMessage()); return map; } /** * Interception catch custom exception MyException.class * @param ex * @return */ @ResponseBody @ExceptionHandler(value = MyException.class) public Map myErrorHandler(MyException ex) { Map map = new HashMap(); map.put("code", ex.getCode()); map.put("msg", ex.getMsg()); return map; } }
3. Exception is thrown in the controller for testing.
@RequestMapping("/home") public String home() throws Exception { // throw new Exception("Sam error"); throw new MyException("101", "Sam error"); }
Start the application, visit: http://localhost:8080/home, display the following json content normally, which proves that the custom exception has been successfully intercepted.
{"msg":"Sam error","code":"101"}
*If you do not need to return json data, but want to render a page template and return it to the browser, you can do this in mycontrolleradvise:
@ExceptionHandler(value = MyException.class) public ModelAndView myErrorHandler(MyException ex) { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("error"); modelAndView.addObject("code", ex.getCode()); modelAndView.addObject("msg", ex.getMsg()); return modelAndView; }
In the templates directory, add error.ftl (freemarker is used here) to render:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Error page</title> </head> <body> <h1>${code}</h1> <h1>${msg}</h1> </body> </html>
Restart the application. http://localhost:8080/home displays the content of the error page.
Add: if all exception handling returns json, @ restcontrolleradvise can be used instead of @ controlleradvise, so that @ ResponseBody does not need to be added to the method.
Reprint link: https://my.oschina.net/langwanghuangshifu/blog/2246890