@ControllerAdvice 全域性異常響應頁面和 JSON

Dongguabai發表於2020-12-03

我這裡頁面以 Thymeleaf 為例子,相關配置:

spring:
  thymeleaf:
    cache: false
    mode: HTML5
    encoding: UTF-8
    prefix: classpath:/templates/

判斷是否是 AJAX:

public static boolean isAjaxRequest(HttpServletRequest request) {
  	return request.getHeader("x-requested-with") != null;
}

異常攔截器:

/**
 * @author Dongguabai
 * @Description
 * @Date 建立於 2020-12-02 10:43
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    private static final String ERROR_PAGE = "error";

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Object handleException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Exception e) throws UnsupportedEncodingException {
        if (isAjaxRequest(httpServletRequest)){
             //這裡返回專案中自定義的統一響應物件即可
            return json(e);
        }
        return view(e);
    }

  這裡返回專案中自定義的統一響應物件即可
    private ResponseX json(Exception e) {
        return new ResponseX();
    }
 
		//這裡返回 ModelAndView 
    public ModelAndView view(Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setStatus(HttpStatus.BAD_REQUEST);
        modelAndView.setViewName(ERROR_PAGE);
        modelAndView.addObject("msg","msg");
        modelAndView.addObject("code","code");
        return modelAndView;
    }
}

error.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <head th:insert="fragments/header"/>
    <title>error</title>
</head>
<body>
  <span th:text="${code}" ></span> - <span th:text="${msg}" ></span>
</body>
</html>

這裡補充說明下,建議不要使用攔截器做,當然不是說攔截器不行(處理響應流即可),主要是攔截器其實是無法處理 Controller 中的異常的:

org.springframework.web.servlet.DispatcherServlet#triggerAfterCompletion

    private void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, Exception ex) throws Exception {
        if (mappedHandler != null) {
            mappedHandler.triggerAfterCompletion(request, response, ex);
        }

        throw ex;
    }

相關文章