SpringBoot 异常处理

异常处理最佳实践

根据个人工做经从来看,我主要遵循如下几点:html

  1. 尽可能不要在代码中写try...catch.finally把异常吃掉。
  2. 异常要尽可能直观,防止被他人误解
  3. 将异常分为如下几类,业务异常,登陆状态无效异常,(虽已登陆,且状态有效)未受权异常,系统异常(JDK中定义Error和Exception,好比NullPointerException, ArithmeticException 和 InputMismatchException)
  4. 能够在某个特定的Controller中处理异常,也能够使用全局异常处理器。尽可能使用全局异常处理器

使用@ControllerAdvice注释全局异常处理器

@ControllerAdvice
public class GlobalExceptionHandler implements ApplicationContextAware {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @ExceptionHandler
    public Object businessExceptionHandler(Exception exception, HttpServletRequest req) {
        DtoResult response = new DtoResult();

        if (exception instanceof BusinessException) {
            int code = ((BusinessException) exception).getErrorCode();
            response.setCode(code > 0 ? code : DtoResult.STATUS_CODE_BUSINESS_ERROR);
            response.setMessage(exception.getMessage());
        } else if (exception instanceof NotAuthorizedException) {
            response.setCode(DtoResult.STATUS_CODE_NOT_AUTHORIZED);
            response.setMessage(exception.getMessage());
        } else {
            response.setCode(DtoResult.STATUS_CODE_SYSTEM_ERROR);
            String profile = applicationContext.getEnvironment().getProperty("spring.profiles.active");
            if (profile != GlobalConst.PROFILE_PRD) {
                response.setMessage(exception.toString());
            } else {
                response.setMessage("系统异常");
            }
            logger.error("「系统异常」", exception);
        }

        String contentTypeHeader = req.getHeader("Content-Type");
        String acceptHeader = req.getHeader("Accept");
        String xRequestedWith = req.getHeader("X-Requested-With");
        if ((contentTypeHeader != null && contentTypeHeader.contains("application/json"))
                || (acceptHeader != null && acceptHeader.contains("application/json"))
                || "XMLHttpRequest".equalsIgnoreCase(xRequestedWith)) {
            HttpStatus httpStatus = HttpStatus.OK;
            if (response.getCode() == DtoResult.STATUS_CODE_SYSTEM_ERROR) {
                httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
            }
            return new ResponseEntity<>(response, httpStatus);
        } else {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("detailMessage", response.getMessage());
            modelAndView.addObject("url", req.getRequestURL());
            modelAndView.setViewName("error");
            return modelAndView;
        }
    }
}
  1. 使用@ControllerAdvice生命该类中的@ExceptionHandler做用于全局
  2. 使用@ExceptionHandler注册异常处理器,能够注册多个,可是不能重复,好比注册两个方法都用于处理Exception是不行的。
  3. 使用HttpServletRequest中的header检测请求是否为ajax, 若是是ajax则返回json(即ResponseEnttiy<>), 若是为非ajax则返回view(即ModelAndView)

thymeleaf模板标签解析错误

themyleaf默认使用HTML5模式,此模式比较严格,好比当标签没有正常闭合,属性书写不正确时都会报错,好比如下格式java

# meta标签没有闭合
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>程序出错了 -  智联</title>
</head>
<body>
<p>程序出错了...</p>
<p>请求地址:<span th:text="${url}"></span></p>
<p>详情:<span th:text="${detailMessage}"></span></p>
</body>
</html>

# 属性v-cloak不符合格式
<div v-cloak></div>

解决方法
能够在配置文件中增长 spring.thymeleaf.mode=LEGACYHTML5 配置项,默认状况下是 spring.thymeleaf.mode=HTML5,
LEGACYHTML5 须要搭配第三方库 nekohtml 才能够使用。web

# 1.在 pom.xml 中增长以下内容:
<!-- https://mvnrepository.com/artifact/net.sourceforge.nekohtml/nekohtml -->
<dependency>
    <groupId>net.sourceforge.nekohtml</groupId>
    <artifactId>nekohtml</artifactId>
    <version>1.9.22</version>
</dependency>

# 2.修改 application.properties 为:
############################## thymeleaf ##############################
spring.thymeleaf.cache=false
# spring.thymeleaf.mode=HTML5
spring.thymeleaf.mode=LEGACYHTML5
############################## thymeleaf ##############################

参考文档

themyleaf 参考文档

异常处理

相关文章
相关标签/搜索