Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 535|回复: 0

全局异常处理区分返回响应类型是页面还是JSON

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-24 12:15:33 | 显示全部楼层 |阅读模式

    一、准备工作

    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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-1-22 19:05 , Processed in 0.063154 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表