• 全局异常处理区分返回响应类型是页面还是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

  • 相关阅读:
    NDBCLuster && MySQL Cluster 转
    Publisher FAQ | Readability: Enjoy Reading. Support Writing.
    Eucalyptus Cloud Computing Software
    Oracle Coherence
    hbase note
    使用python代码实现三叉搜索树高效率”自动输入提示”功能
    Facebook 的系统架构 肇凯博客
    CentOS Linux 环境 Rails 安装记录
    linux socket网络编程进阶推荐阅读开源项目转
    HandlerSocket
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/12187259.html
Copyright © 2020-2023  润新知