建立 MyControllerAdvice,并添加 @ControllerAdvice注解。html
package com.sam.demo.controller; import org.springframework.ui.Model; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; /** * controller 加强器 */ @ControllerAdvice public class MyControllerAdvice { /** * 应用到全部@RequestMapping注解方法,在其执行以前初始化数据绑定器 * * @param binder */ @InitBinder public void initBinder(WebDataBinder binder) { } /** * 把值绑定到Model中,使全局@RequestMapping能够获取到该值 * * @param model */ @ModelAttribute public void addAttributes(Model model) { model.addAttribute("author", "Magical Sam"); } /** * 全局异常捕捉处理 * * @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; } }
启动应用后,添加了@ExceptionHandler、@InitBinder、@ModelAttribute 注解的方法,都会做用于添加@RequestMapping 注解的方法之上。java
@ModelAttribute:在Model上设置的值,对于全部添加了@RequestMapping注解的方法,均可以经过ModelMap获取设置的值,以下:web
//经过modelMap.get()获取 @RequestMapping("/home") public String home(ModelMap modelMap){ System.out.println(modelMap.get("author")); } //经过@ModelAttribute获取 @RequestMapping("/home") public String home(@ModelAttribute("author") String author){ System.out.println(author); }
@ExceptionHandler拦截了异常,咱们能够经过该注解实现自定义异常处理。其中,@ExceptionHandler 配置的 value 指定须要拦截的异常类型,上面拦截了 Exception.class 这种异常。spring
spring boot 默认状况下会映射到 /error 进行异常处理,可是提示并不十分友好,下面自定义异常处理,提供友好展现。json
1.编写自定义异常类:浏览器
package com.demo.custom; 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 }
注:spring 对于 RuntimeException 异常才会进行事务回滚。app
二、编写全局异常处理类测试
建立 MyControllerAdvice.java:ui
package com.sam.demo.controller; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import java.util.HashMap; import java.util.Map; @ControllerAdvice public class MyControllerAdvice { /** * 全局异常捕捉处理 * * @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; } /** * 拦截捕捉自定义异常 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; } }
@RequestMapping("/home") public String home() throws Exception { //throw new Exception("Sam 错误"); throw new MyException("101", "Sam 错误"); }
启动应用,访问:http://localhost:8080/home ,正常显示如下json内容,证实自定义异常已经成功被拦截。this
{"msg":"Sam 错误","code":"101"}
若是不须要返回json数据,而要渲染某个页面模板返回给浏览器,那么MyControllerAdvice中能够这么实现:
@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; }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>错误页面</title> </head> <body> <h1>${code}</h1> <h1>${msg}</h1> </body> </html>
重启应用,http://localhost:8080/home 显示自定的错误页面内容。
补充:若是所有异常处理返回json,那么可使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就能够不须要添加 @ResponseBody。