SpringBoot 异常处理

异常处理最佳实践

根据我的工作经历来看,我主要遵循以下几点:

  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模式,此模式比较严格,比如当标签没有正常闭合,属性书写不正确时都会报错,比如以下格式

# 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 才可以使用。

# 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 参考文档

异常处理

posted on 2017-09-26 16:38  James.H.Fu  阅读(2062)  评论(0编辑  收藏  举报

导航