Spring Cloud Gateway配置自定义异常返回

0. 前言

最近搞微服务的全家桶,用到的Spring Cloud Gateway 这个组件。需要对这个网关抛出的异常进行自定义。网关的异常处理跟单体SpringBoot的全局异常处理还有点不一样。

单体全局异常处理,是采用@RestControllerAdvice 这个注解来实现的。微服务Gateway是采用另外的方式来实现的。

1. 单体自定义异常返回

CustomException.java

1 package com.wunaozai.config.advice;
 2
 3 /**
 4  * 自定义异常类(运行时异常)
 5  * @author wunaozai
 6  * @date 2018-06-27
 7  */
 8 public class CustomException extends RuntimeException {
 9
10     private static final long serialVersionUID = 6304501072268270030L;
11
12     public CustomException(String msg) {
13         this(500, msg);
14     }
15     public CustomException(int code, String msg) {
16         this(code, msg, null);
17     }
18     public CustomException(String msg, Object data) {
19         this(500, msg, data);
20     }
21     public CustomException(int code, String msg, Object data) {
22         super(msg);
23         this.code = code;
24         this.msg = msg;
25         this.data = data;
26     }
27
28
29     /**
30      * 异常代码
31      */
32     private int code;
33     /**
34      * 异常信息
35      */
36     private String msg;
37     /**
38      * 异常调试信息
39      */
40     private Object data;
41
42     /**
43      * 异常代码
44      * @return code
45      */
46     public int getCode() {
47         return code;
48     }
49     /**
50      * 异常代码
51      * @param code 异常代码
52      */
53     public void setCode(int code) {
54         this.code = code;
55     }
56     /**
57      * 异常信息
58      * @return msg
59      */
60     public String getMsg() {
61         return msg;
62     }
63     /**
64      * 异常信息
65      * @param msg 异常信息
66      */
67     public void setMsg(String msg) {
68         this.msg = msg;
69     }
70     /**
71      * 异常调试信息
72      * @return data
73      */
74     public Object getData() {
75         return data;
76     }
77     /**
78      * 异常调试信息
79      * @param data 异常调试信息
80      */
81     public void setData(Object data) {
82         this.data = data;
83     }
84 }

CustomControllerAdvice.java

1 package com.wunaozai.config.advice;
 2
 3 import java.util.HashMap;
 4 import java.util.Map;
 5
 6 import org.springframework.ui.Model;
 7 import org.springframework.web.bind.WebDataBinder;
 8 import org.springframework.web.bind.annotation.ExceptionHandler;
 9 import org.springframework.web.bind.annotation.InitBinder;
10 import org.springframework.web.bind.annotation.ModelAttribute;
11 import org.springframework.web.bind.annotation.RestControllerAdvice;
12
13 import com.baomidou.mybatisplus.extension.api.R;
14
15 /**
16  * 控制器Controller异常处理
17  * @author wunaozai
18  * @Date 2020-03-05
19  */
20 @RestControllerAdvice
21 public class CustomControllerAdvice {
22
23     /**
24      * 应用到所有@RequestMapper 注解方法,在其执行之前初始化数据绑定器
25      * @param binder
26      */
27     @InitBinder
28     public void initBinder(WebDataBinder binder) {
29
30     }
31
32     /**
33      * 把值绑定到Model中,使全局@RequestMapper可以获取到该值
34      * @param model
35      */
36     @ModelAttribute
37     public void addAttributes(Model model) {
38         model.addAttribute("Server", "Wunaozai");
39     }
40
41     @ExceptionHandler(value= {Exception.class, CustomException.class})
42     public R errorHandler(Exception ex){
43         Map map = new HashMap<>();
44         map.put("code", 500);
45         map.put("msg", ex.getMessage());
46         System.out.println("异常Handler.");
47         ex.printStackTrace();
48         //System.out.println(resuserService.count());
49         return R.failed(ex.getMessage());
50     }
51 }

2. 微服务Gateway自定义异常返回

JsonExceptionHandler.java

1 package com.wunaozai.config.exception;
 2
 3 import java.util.HashMap;
 4 import java.util.Map;
 5
 6 import org.springframework.boot.autoconfigure.web.ErrorProperties;
 7 import org.springframework.boot.autoconfigure.web.ResourceProperties;
 8 import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
 9 import org.springframework.boot.web.reactive.error.ErrorAttributes;
10 import org.springframework.cloud.gateway.support.NotFoundException;
11 import org.springframework.context.ApplicationContext;
12 import org.springframework.http.HttpStatus;
13 import org.springframework.web.reactive.function.server.RequestPredicates;
14 import org.springframework.web.reactive.function.server.RouterFunction;
15 import org.springframework.web.reactive.function.server.RouterFunctions;
16 import org.springframework.web.reactive.function.server.ServerRequest;
17 import org.springframework.web.reactive.function.server.ServerResponse;
18
19 import lombok.extern.slf4j.Slf4j;
20
21 /**
22  * 序列化
23  * @author wunaozai
24  * @Date 2020-06-04
25  */
26 @Slf4j
27 public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
28
29     public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
30             ErrorProperties errorProperties, ApplicationContext applicationContext) {
31         super(errorAttributes, resourceProperties, errorProperties, applicationContext);
32     }
33
34     @Override
35     protected Map getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
36         int code = HttpStatus.INTERNAL_SERVER_ERROR.value();
37         Throwable error = super.getError(request);
38 //        if(error instanceof NotFoundException) {
39 //            code = HttpStatus.NOT_FOUND.value();
40 //        }
41         return response(code, this.buildMessage(request, error));
42     }
43
44     /**
45      * 指定响应处理方法为JSON处理的方法
46      * @param errorAttributes
47      */
48     @Override
49     protected RouterFunction getRoutingFunction(ErrorAttributes errorAttributes) {
50         return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
51     }
52
53
54     /**
55      * 根据code获取对应的HttpStatus
56      * @param errorAttributes
57      */
58     @Override
59     protected int getHttpStatus(Map errorAttributes) {
60         int statusCode = (int) errorAttributes.get("code");
61         return statusCode;
62     }
63
64     /**
65      * 构建异常信息
66      * @param request
67      * @param ex
68      * @return
69      */
70     private String buildMessage(ServerRequest request, Throwable ex) {
71         StringBuilder message = new StringBuilder("Failed to handle request [");
72         message.append(request.methodName());
73         message.append(" ");
74         message.append(request.uri());
75         message.append("]");
76         if (ex != null) {
77             message.append(": ");
78             message.append(ex.getMessage());
79         }
80         return message.toString();
81     }
82
83     /**
84      * 构建返回的JSON数据格式
85      * @param status        状态码
86      * @param errorMessage  异常信息
87      * @return
88      */
89     public static Map response(int status, String errorMessage) {
90         Map map = new HashMap<>();
91         map.put("code", status);
92         map.put("message", errorMessage);
93         map.put("data", null);
94         log.error(map.toString());
95         return map;
96     }
97 }

ExceptionHandlerConfiguration.java

1 package com.wunaozai.config.exception;
 2
 3 import java.util.Collections;
 4 import java.util.List;
 5
 6 import org.springframework.beans.factory.ObjectProvider;
 7 import org.springframework.boot.autoconfigure.web.ResourceProperties;
 8 import org.springframework.boot.autoconfigure.web.ServerProperties;
 9 import org.springframework.boot.context.properties.EnableConfigurationProperties;
10 import org.springframework.boot.web.reactive.error.ErrorAttributes;
11 import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
12 import org.springframework.context.ApplicationContext;
13 import org.springframework.context.annotation.Bean;
14 import org.springframework.context.annotation.Configuration;
15 import org.springframework.core.Ordered;
16 import org.springframework.core.annotation.Order;
17 import org.springframework.http.codec.ServerCodecConfigurer;
18 import org.springframework.web.reactive.result.view.ViewResolver;
19
20 /**
21  * 自定义异常处理
22  * https://www.cnblogs.com/viaiu/p/10403557.html
23  * @author wunaozai
24  * @Date 2020-06-04
25  */
26 @Configuration
27 @EnableConfigurationProperties({ ServerProperties.class, ResourceProperties.class })
28 public class ExceptionHandlerConfiguration {
29
30     private final ServerProperties serverProperties;
31
32     private final ApplicationContext applicationContext;
33
34     private final ResourceProperties resourceProperties;
35
36     private final List viewResolvers;
37
38     private final ServerCodecConfigurer serverCodecConfigurer;
39
40     public ExceptionHandlerConfiguration(ServerProperties serverProperties, ResourceProperties resourceProperties,
41             ObjectProvider> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer,
42             ApplicationContext applicationContext) {
43         this.serverProperties = serverProperties;
44         this.applicationContext = applicationContext;
45         this.resourceProperties = resourceProperties;
46         this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
47         this.serverCodecConfigurer = serverCodecConfigurer;
48     }
49
50     @Bean
51     @Order(Ordered.HIGHEST_PRECEDENCE)
52     public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
53         JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(errorAttributes, this.resourceProperties,
54                 this.serverProperties.getError(), this.applicationContext);
55         exceptionHandler.setViewResolvers(this.viewResolvers);
56         exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
57         exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
58         return exceptionHandler;
59     }
60 }

处理前异常返回

Spring Cloud Gateway配置自定义异常返回

自定义后异常返回

参考资料: https://www.cnblogs.com/viaiu/p/10403557.html

本文地址: https://www.cnblogs.com/wunaozai/p/13043979.html

Original: https://www.cnblogs.com/wunaozai/p/13043979.html
Author: 无脑仔的小明
Title: Spring Cloud Gateway配置自定义异常返回

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/540649/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • JAVA中Integer的==和equals注意

    “equals”比较equals(Object obj)方法,在equals(Object obj)方法中,会先判断参数中的对象obj是否是Integer同…

    Java 2023年5月29日
    077
  • mybatis 报错:Caused by: org.apache.ibatis.binding.BindingException: Parameter ” not found

    问题描述: Caused by: org.apache.ibatis.binding.BindingException: Parameter ” not found 问…

    Java 2023年5月30日
    069
  • Linux安装mysql8.0.29详细教程

    我在上午卸载了陪伴我多年的mysql5.7,现在准备安装mysql8.0。 1)根据自己电脑的位数和你cpu架构相符的安装 2))选完之后找到RPM Bundle点击下载 1、登录…

    Java 2023年6月13日
    069
  • 千万不要在方法上打断点!有坑!

    你好呀,我是歪歪。 我上周遇到了一个莫名其妙的搞心态的问题,浪费了我好几个小时。 气死我了,拿这几个小时来敲(摸)代(摸)码(鱼)不香吗? 主要是最后问题的解决方式也让我特别的无语…

    Java 2023年6月5日
    088
  • 浅谈SpringCloud五大组件

    spring cloud五大组件分别为: 服务发现–Netflix Eureka 客户端负载均衡–Netflix Ribbon 断路器–Netf…

    Java 2023年5月30日
    067
  • 如何阅读

    推荐一本好书 如何阅读一本书如果你还在为看不懂文档或看得很慢而烦恼,看了也很快的就忘了,不停的在原地踏步。并不是因为你笨,而是因为你没有找到一个阅读的方法。贯穿始终的一个点就是,提…

    Java 2023年6月5日
    081
  • BLOG-1_JavaHomework_Summary

    PTA大作业_阶段性总结 前言 虽说上学期为了助眠看了一点 Java 但是散而不精,看而不敲,所以这学期正式学 Java 并没有想象中那么容易… 对 java和 C/C…

    Java 2023年6月5日
    0105
  • JAVA SSH 框架介绍(转)

    转载自:http://www.admin10000.com/document/150.html SSH 为 struts+spring+hibernate 的一个集成框架,是目前较…

    Java 2023年5月29日
    0114
  • SpringBoot整合knife4j

    一、 knife4j简介 1、简介 knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,它封装了swagger。前身是swagger-bootst…

    Java 2023年5月30日
    084
  • 创建链表

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月5日
    077
  • 浏览器书签同步收藏扩展插件更新,浏览器书签插件需要那么功能?

    新增:浏览器插件新增简介,标签,星标,封面图等操作功能 新增:浏览器插件收藏快捷键启动(浏览器插件扩展自定义快捷键) 浏览器通用默认快捷键 win:Ctrl+Shift+S mac…

    Java 2023年6月5日
    082
  • Java—Stream进阶

    由于本文需要有一定的Stream基础,不懂什么是Stream的同学请移步:Java—Stream入门 操作分类 graph LR 操作分类 — 中间操作 终…

    Java 2023年6月7日
    083
  • 初识Java

    C&C++ Java应运而生 以这样的构想进行编写 语法类似C 没有指针 没有内存管理 可移植性 面向对象 类型安全 高质量的类库 …… 可移植性 Java…

    Java 2023年6月9日
    096
  • Java基本数据类型

    对于Java语言来说,它是一个强类型语言。因此对于所有变量的生成,都必须先声明一种类型。Java中对于数据类型主要分为引用数据类型和基本数据类型。本节主要对基本数据类型做一个介绍。…

    Java 2023年6月5日
    065
  • Java使用Jsoup解析网页代码实现

    本文转载自:https://www.cnblogs.com/boy1025/p/5040495.html,有少许修改 通俗的讲,Jsoup就是一个解析网页的工具,官方解释: 1.解…

    Java 2023年5月29日
    066
  • 二进制妙用之位标记

    二进制妙用之位标记 1. 使用背景 已知一个字符串 String s = “abcdefg”,需要判断字符串中是否存在重复的字符。 2. 常规实现 根据Hashset特性判断重复。…

    Java 2023年6月13日
    081
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球