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 參考文檔

異常處理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM