全局異常處理區分返回響應類型是頁面還是JSON


一、准備工作

1.1 導入依賴

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- thymeleaf模板依賴 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

1.2 在 /templates 目錄下新建 error 頁面

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head lang="en">
	<meta charset="UTF-8"/>
	<title>統一頁面異常處理</title>
</head>
<body>
<h1>統一頁面異常處理</h1>
<div th:text="${message}"></div>
</body>
</html>

1.3 定義異常基類

@Data
public class BaseException extends RuntimeException {

    /**
     * 錯誤碼
     */
    private Integer code;

    /**
     * 錯誤提示
     */
    private String message;

    public BaseException(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

}  

二、根據 URL 后綴區分

2.1 創建 URL 異常類

@Data
public class UrlSuffixException extends BaseException {

    public UrlSuffixException(Integer code, String message) {
        super(code, message);
    }

}

2.2 申明接口

@Controller
@RequestMapping("/error")
public class ExceptionController {


    @RequestMapping("/url.html")
    public void throwsUrlSuffixExceptionByHtml() {
        throw new UrlSuffixException(0001, "throwUrlSuffixException");
    }

    @RequestMapping("/url.json")
    public void throwsUrlSuffixExceptionByJson() {
        throw new UrlSuffixException(0001, "throwUrlSuffixException");
    }
}

2.3 全局異常處理 UrlSuffixException

@ControllerAdvice
public class GlobalExceptionHandle {

    private static final String URL_SUFFIX_JSON = ".json";

    @ExceptionHandler(UrlSuffixException.class)
    public ModelAndView handleException(HttpServletRequest request, UrlSuffixException exception) {
        String url = request.getRequestURL().toString();
        if (url.endsWith(URL_SUFFIX_JSON)) {
            ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
            modelAndView.addObject("code", exception.getCode());
            modelAndView.addObject("message", exception.getMessage());
            return modelAndView;
        } else {
            ModelAndView modelAndView = new ModelAndView("/error");
            modelAndView.addObject("message", exception.getMessage());
            return modelAndView;
        }
    }

}

2.4 測試

訪問http://localhost:8080/error/url.json

{
    message: "throwUrlSuffixException",
    code: 1001
}

訪問 ``http://localhost:8080/error/url.html`

三、根據注解區分

3.1 創建注解異常類

@Data
public class AnnotationException extends BaseException {

    public AnnotationException(Integer code, String message) {
        super(code, message);
    }
}

3.2 申明接口

@Controller
@RequestMapping("/error")
public class ExceptionController {
    @RequestMapping("/annotation/html")
    public void throwsAnnotationExceptionByHtml() {
        throw new AnnotationException(2000, "throwAnnotationException");
    }

    @RequestMapping("/annotation/json")
    @ResponseBody
    public String throwsAnnotationExceptionByJson() {
        throw new AnnotationException(2001, "throwAnnotationException");
    }
}    

3.3 全局異常處理

@ControllerAdvice
public class GlobalExceptionHandle {

    @ExceptionHandler(AnnotationException.class)
    public ModelAndView handleException(AnnotationException exception, HandlerMethod handler) {
        if (isReturnJson(handler)) {
            ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
            modelAndView.addObject("code", exception.getCode());
            modelAndView.addObject("message", exception.getMessage());
            return modelAndView;
        } else {
            ModelAndView modelAndView = new ModelAndView("/error");
            modelAndView.addObject("message", exception.getMessage());
            return modelAndView;
        }
    }
  
    private boolean isReturnJson(HandlerMethod handler) {
        if (handler.getBeanType().isAnnotationPresent(RestController.class)) {
            return true;
        }
        Method method = handler.getMethod();
        if (method.isAnnotationPresent(ResponseBody.class)) {
            return true;
        }
        return false;
    }    
}    

3.4 測試

訪問 http://localhost:8080/error/annotation/json

{
    message: "throwAnnotationException",
    code: 2001
}

訪問 ``http://localhost:8080/error/annotation/html`

四、根據是否是 AJAX 請求區分

4.1 創建異常類

@Data
public class AjaxRequestException extends BaseException {
    public AjaxRequestException(Integer code, String message) {
        super(code, message);
    }
}

4.2 申明接口

@Controller
@RequestMapping("/error")
public class ExceptionController {
    @RequestMapping("/request")
    @ResponseBody
    public String throwsAjaxRequestException() {
        throw new AjaxRequestException(3000, "throwAjaxRequestException");
    }
}    

4.3 全局異常處理

@ControllerAdvice
public class GlobalExceptionHandle {

	@ExceptionHandler(AjaxRequestException.class)
    public ModelAndView handleException(HttpServletRequest request, AjaxRequestException exception) {
        if (isAjaxRequest(request)) {
            ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
            modelAndView.addObject("code", exception.getCode());
            modelAndView.addObject("message", exception.getMessage());
            return modelAndView;
        } else {
            ModelAndView modelAndView = new ModelAndView("/error");//配置需要跳轉的Controller方法
            modelAndView.addObject("message", exception.getMessage());
            return modelAndView;
        }
    }

    private boolean isAjaxRequest(HttpServletRequest request) {
        String accept = request.getHeader("accept");
        if (accept != null && accept.indexOf("application/json") != -1) {
            return true;
        }

        String xRequestedWith = request.getHeader("X-Requested-With");
        if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1) {
            return true;
        }

        String uri = request.getRequestURI();
        if (uri.endsWith(".json") || uri.endsWith(".xml")) {
            return true;
        }

        String ajax = request.getParameter("__ajax");
        if (ajax.endsWith("json") || ajax.endsWith("xml")) {
            return true;
        }
        return false;
    }
}    

4.4 測試

訪問http://localhost:8080/error/request

ajax 形式訪問http://localhost:8080/error/request


免責聲明!

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



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