Spring Boot 中的异常处

Spring Boot 框架异常处理有五种处理方式,从范围来说包括有全局异常捕获处理方式和局部异常捕获处 理方式
自定义异常错误页
 在遇到异常时,Spring Boot 会自动跳到一个默认的异常页面,如请求上述 http://localhost:8080/exceptionMethod 路径时发生 500 错误,Spring Boot 会有一个默认的页面 展示给用户,如图所示

Spring Boot 默认的异常处理机制是程序中出现了异常 Spring Boot 就会请求 /error 的 url 。
这里以 Thymleaf 为例,Thymleaf 页面模板默认处于 classpath:/templates/ 下, 因此在该目录下创建 error.html 文件即可
使用@ExceptionHandler注解处理局部异常
SpringMVC 提供了@ExceptionHandler 这个注解,在 SpringBoot 里面,我们同样可以 使用它来做异常捕获。直接在对应的 Controller 里面增加一个异常处理的方法,并使用 @ExceptionHandler 标识它即可,属于局部处理异常
@Controller
public class ExceptionController {
    private static final Logger log = LoggerFactory.getLogger(ExceptionController.class);
    @RequestMapping("/exceptionMethod")
    public String exceptionMethod(Model model) throws Exception {
        model.addAttribute("msg", "没有抛出异常");
        int num = 1/0;
        log.info(String.valueOf(num));
        return "index";
    }
    /**
     * 描述:捕获 ExceptionController 中的 ArithmeticException 异常
     * @param model 将Model对象注入到方法中
     * @param e 将产生异常对象注入到方法中
     * @return 指定错误页面
     */
    @ExceptionHandler(value = {ArithmeticException.class})
    public String arithmeticExceptionHandle(Model model, Exception e) {
        model.addAttribute("msg","@ExceptionHandler" + e.getMessage());        log.info(e.getMessage());
        return "error";
    }
}
使用 @ControllerAdvice 注解处理全局异常
实际开发中,需要对异常分门别类的进行处理,使用 @ControllerAdvice + @ExceptionHandler 注解能够处理全局异常,这种方式推荐使用,可以根据不同的异常对不 同的异常进行处理。
   使用方式:定义一个类,使用 @ControllerAdvice 注解该类,使用 @ExceptionHandler 注解方法,这里我定义了一个 GlobalException 类表示来处理全局异常,代码如下:

//GlobalException.java
@ControllerAdvice
public class GlobalException {
    private static final Logger log = LoggerFactory.getLogger(GlobalException.class);
    /**
     * 描述:捕获 ArithmeticException 异常
     * @param model 将Model对象注入到方法中
     * @param e 将产生异常对象注入到方法中
     * @return 指定错误页面
     */
  
  @ExceptionHandler(value = {ArithmeticException.class})
    public String arithmeticExceptionHandle(Model model, Exception e) {
        model.addAttribute("msg", "@ControllerAdvice + @ExceptionHandler :" + e.getMessage());
        log.info(e.getMessage());
        return "error";
    }
}
如果需要处理其他异常,如 NullPointerException 异常,则只需要在 GlobalException 类 中定义一个方法使用 @ExceptionHandler(value = {NullPointerException.class}) 注解该方法, 在该方法内部处理异常就可以了。
配置 SimpleMappingExceptionResolver 类处理异常
通过配置 SimpleMappingExceptionResolver 类处理异常也是全局范围的,通过将 SimpleMappingExceptionResolver 类注入到 Spring 容器,代码如下:

@Configuration
public class GlobalException {
    @Bean
    public SimpleMappingExceptionResolver
    getSimpleMappingExceptionResolver(){
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        /*
         * 参数一:异常的类型,注意必须是异常类型的全名
         * 参数二:视图名称
         */
        mappings.put("java.lang.ArithmeticException", "error");
        //设置异常与视图映射信息的
        resolver.setExceptionMappings(mappings);
        return resolver;
    }
}
实现 HandlerExceptionResolver 接口处理异常
通过实现 HandlerExceptionResolver 接口处理异常,首先编写类实现 HandlerExceptionResolver 接口,代码如下:

@Configuration
public class HandlerExceptionResolverImpl implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                                         Exception ex) {
        ModelAndView modelAndView = new ModelAndView();
       modelAndView.addObject("msg", "实现 HandlerExceptionResolver 接口处理异常");
        //判断不同异常类型,做不同视图跳转
        if(ex instanceof ArithmeticException){
            modelAndView.setViewName("error");
        }
        return modelAndView;
    }
}
 当然了,异常很多,比如还有 RuntimeException,数据库还有一些查询或者操作异常等 等。由于 Exception 异常是父类,所有异常都会继承该异常,所以我们可以直接拦截 Exception 异常,一劳永逸,代码如下:

@ControllerAdvice
public class GlobalException{
    private static final Logger log= LoggerFactory.getLogger(GlobalException.class);
    /**
     * 系统异常 预期以外异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    //@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public JsonResult handleUnexpectedServer(Model model,Exception ex) {
        model.addAttribute("msg", "系统发生异常,请联系管理员");
        log.info(e.getMessage());
        return "error";
    }
}

实际项目中,可以把拦截 Exception 异常写在 GlobalException最下面,如果都没有找到,最后再拦截一下 Exception 异常,保证异常得到处理。
原文地址:https://www.cnblogs.com/tszr/p/15442954.html