zoukankan      html  css  js  c++  java
  • 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 参考文档

    异常处理

  • 相关阅读:
    使用OTT处理oracle中的对象(一) OTT配置
    mvc全局过滤器和httpmodule的执行顺序
    Cookie的跨域问题
    Request[]与Request.Params[] 差别
    Introduction to Partial View
    MVC异常过滤器在三种作用范围下的执行顺序
    System.Web.UI.Page事件执行顺序
    Controlling Session Behavior in Asp.Net MVC4
    MVC复杂类型的模型绑定
    ROW_NUMBER分页
  • 原文地址:https://www.cnblogs.com/fuhongwei041/p/7597531.html
Copyright © 2011-2022 走看看