Spring Cloud Gateway 全局异常处理和自定义错误响应

2024-05-13

我有一个自定义过滤器,可以在使用 Spring Cloud Gateway 调用实际 API 之前对每个请求进行身份验证。 Spring Cloud中有没有办法像Spring提供@ControllerAdvice一样集中处理异常?我想全局处理异常并从网关返回自定义错误响应。


一旦身份验证过滤器引发异常,您可以通过重写 DefaultErrorAttributes 类来自定义错误响应。

@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {


    private static final Logger logger = LoggerFactory.getLogger(GlobalErrorAttributes.class);

    public GlobalErrorAttributes() {
    }

    public GlobalErrorAttributes(boolean includeException) {
        super(includeException);
    }

    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request,
                                                  boolean includeStackTrace) {
        Throwable error = this.getError(request);
        logger.error("Error occured", error);
        MergedAnnotation<ResponseStatus> responseStatusAnnotation = MergedAnnotations
                .from(error.getClass(), MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(ResponseStatus.class);
        HttpStatus errorStatus = findHttpStatus(error, responseStatusAnnotation);
        logger.info("errorStatus: {}", errorStatus);
        Map<String, Object> map = super.getErrorAttributes(request, includeStackTrace);
        String errorCode = getErrorCode(map, errorStatus);
        map.remove("timestamp");
        map.remove("path");
        map.remove("error");
        map.remove("requestId");
        map.put("errorCode", errorCode);
        return map;
    }

    private HttpStatus findHttpStatus(Throwable error, MergedAnnotation<ResponseStatus> responseStatusAnnotation) {
        if (error instanceof ResponseStatusException) {
            return ((ResponseStatusException) error).getStatus();
        }
        return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(INTERNAL_SERVER_ERROR);
    }

    private String getErrorCode(Map<String, Object> map, HttpStatus errorStatus) {
        String errorCode;
        switch (errorStatus) {
            case UNAUTHORIZED:
                errorCode = "401 UnAuthorized";
                break;
            case NOT_FOUND:
                logger.error("The url:{} is not found", map.get("path"));
                errorCode = "404 Not Found";
                map.put(MESSAGE, "NOT FOUND");
                break;
            case METHOD_NOT_ALLOWED:
                logger.error("Invalid HTTP Method type for the url: {}", map.get("path"));
                errorCode = "405 Method Not Allowed";
                break;
            default:
                logger.error("Unexpected error happened");
                logger.error("errorstatus is : {}", errorStatus);
                errorCode = "500 Internal Server Error";
                map.put(MESSAGE, "Unexpected Error");
        }
        return errorCode;
    }
}

输出将如下所示:

{
   "status": 401,
   "message": "Invalid Access Token",
   "error_code": "401 UnAuthorized"
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Cloud Gateway 全局异常处理和自定义错误响应 的相关文章

随机推荐

  • “mvn”不被识别为内部或外部命令、可操作程序或批处理文件

    可能是之前问过问题 但我发现了非常奇怪的错误 当我跑步时mvn versionbin 中的命令给出了版本和其他信息 但是 当我跑到垃圾箱外面时 它会出现异常 下面提到的结果 C Program Files apache maven 3 0
  • 从字符串中的链接中删除基本 URL

    我有一个带有图像链接的字符串 image link raw http website com files 2012 10 image001 png 现在我想删除http website com然后就得到 files 2012 10 imag
  • 无法执行'x86_64-conda_cos6-linux-gnu-gcc':没有这样的文件或目录(pysam安装)

    我正在尝试安装 pysam 执行后 python path to pysam master setup py build 这个错误的产生是 unable to execute x86 64 conda cos6 linux gnu gcc
  • 升级到 5.4 但“php -v”仍然返回旧版本

    我使用的是 OSX Lion 10 7 5 正如建议的如何在 Mac OS X 中升级 PHP https stackoverflow com questions 2526085 how do i upgrade php in mac os
  • 什么是多重重继承?

    我将以下称为 多重重新继承 直接继承一个类一次 并通过继承其一个或多个后代来间接继承一次或多次 通过继承一个类的两个或多个后代来间接继承一个类两次或多次 我想知道它是否存在以及如何明确访问嵌入的子对象 1 Professional C 2n
  • 在第一页加载时触发 jquery 脚本,然后不再为该用户触发?

    我在我的网站上使用这个 jQuery 模态窗口脚本 http www zurb com playground reveal modal plugin http www zurb com playground reveal modal plu
  • Bipush 在 JVM 中如何工作?

    我知道 iload 接受整数 1 到 5 但是如何使用 bipush 指令扩展到更高的数字 特定整数如何与字节码一起存储 有几种不同的指令可用于推送整数常量 最小的是iconst 指令 这些只是一个字节 因为该值是在操作码本身中编码的 ic
  • 使 flake8 区分未定义函数和星型导入

    我有一个相当大的项目 我试图在发布之前清理它 但是当我运行 flake8 时 我得到了大量的 F405
  • lambda 表达式是多线程的吗?

    lambda 表达式是多线程的吗 假设当你将数学公式编写为 lambda 方法时 当你将其传递给另一个方法时 它会是多线程的吗 不是100 清楚你问的是什么 您是否想问 lambda 是否自然地在不同的线程上运行 如果是这样 则它们只是 S
  • Swing GUI 出现 IntelliJ 错误“contentPane 无法设置为 null。”从终端编译时

    当我从 IntelliJ 编译我的项目时 没有任何问题 我的程序运行顺利 但是当我尝试使用 javac 从终端编译它时 警告 注意 Victor presentation TableControllerMenu java 使用未经检查或不安
  • 加载 highchart 时 Android 错误膨胀类

    我正在尝试加载highcharts via Dialog 下面是我的代码 Gradle implementation com highsoft highcharts highcharts 9 0 1 XML
  • 如何使组合键唯一?

    I am making a database of students in one school Here is what I have so far 如果您不喜欢阅读 请跳至 简而言之 部分 问题是我对这个设计并不满意 我想要的组合gra
  • Recoil 中的动态原子键

    我正在尝试创建一个动态表单 其中表单输入字段是根据 API 返回的数据呈现的 由于atom需要有一个唯一的键 我尝试将它包装在一个函数中 但是每次我更新字段值或重新安装组件 尝试更改选项卡 时 我都会收到一条警告 我在这里做了一个小的运行示
  • 在edittext android中插入imageview

    我想将 imageview 放在 edittext 中 可能吗 我检查了 evernote 应用程序 它能够将照片放在编辑文本部分 我想让我的应用程序完全相同 我如何才能将从图库中选择的图像视图放入编辑文本中 我首先尝试将 imagevie
  • 我们为什么使用序列化?

    为什么我们需要使用序列化 如果我们想通过网络发送一个对象或一段数据 我们可以使用字节流 如果我们想将一些数据保存到磁盘上 我们可以再次使用二进制模式和字节流来保存它 那么使用序列化有什么好处呢 从技术上讲 在低级别上 您的序列化对象也将最终
  • 在 Spark MLlib 上使用 Java 中的 Breeze

    在尝试从Java使用MLlib时 使用微风矩阵运算的正确方法是什么 例如scala 中的乘法很简单 matrix vector 相应的功能在Java中是如何表达的 有一些方法 例如 colon times 可以通过正确的方式调用 breez
  • Python中矩阵元素的双重求和

    基于下面的简化示例 我想在我的代码中 from sympy import import numpy as np init printing x y symbols x y mat Matrix x 1 1 y X 1 2 3 Y 10 20
  • Hive - 线程安全的自动递增序列号生成

    我遇到一种情况 需要将记录插入到特定的 Hive 表中 其中一列需要是自动递增的序列号 即在任何时间点都必须严格遵循 max value 1 规则 记录从许多并行的 Hive 作业插入到这个特定的表中 这些作业每天 每周 每月批量运行 现在
  • 可以在 IE 中的表格行上添加渐变吗?

    当我将鼠标悬停在表格特定部分的表格行上时 我希望背景更改为线性渐变 CSS 很简单 tbody row links tr hover background typical multi browser linear gradient code
  • Spring Cloud Gateway 全局异常处理和自定义错误响应

    我有一个自定义过滤器 可以在使用 Spring Cloud Gateway 调用实际 API 之前对每个请求进行身份验证 Spring Cloud中有没有办法像Spring提供 ControllerAdvice一样集中处理异常 我想全局处理