Spring Cloud Gateway自定义异常处理Exception Handler的方法小结

版本: Spring Cloud 2020.0.3

常见的方法有 实现自己的 DefaultErrorWebExceptionHandler 或 仅实现ErrorAttributes.

方法1: ErrorWebExceptionHandler (仅供示意)

自定义一个 GlobalErrorAttributes:

@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes{

    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
        Throwable error = super.getError(request);

        Map<String, Object> map = super.getErrorAttributes(request, options);
        map.put("status", HttpStatus.BAD_REQUEST.value());
        map.put("message", error.getMessage());
        return map;
    }
}

实现一个

@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    public GlobalErrorWebExceptionHandler(GlobalErrorAttributes gea, ApplicationContext applicationContext,
                                          ServerCodecConfigurer serverCodecConfigurer) {
        super(gea, new WebProperties.Resources(), applicationContext);
        super.setMessageWriters(serverCodecConfigurer.getWriters());
        super.setMessageReaders(serverCodecConfigurer.getReaders());
    }

    //渲染html或json
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(final ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    private Mono<ServerResponse> renderErrorResponse(final ServerRequest request) {

        final Map<String, Object> errorPropertiesMap = getErrorAttributes(request, ErrorAttributeOptions.defaults());

        return ServerResponse.status(HttpStatus.BAD_REQUEST)
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(errorPropertiesMap));
    }
}

方法2, 仅实现一个 ErrorAttributes, 以覆盖默认的 DefaultErrorAttributes

//Spring 默认的就很好了.
@Component
public class GatewayErrorAttributes extends DefaultErrorAttributes {

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

    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request,  ErrorAttributeOptions options) {
        Throwable error = super.getError(request);
        Map<String, Object> errorAttributes = new HashMap<>(8);
        errorAttributes.put("message", error.getMessage());
        errorAttributes.put("method", request.methodName());
        errorAttributes.put("path", request.path());

        MergedAnnotation<ResponseStatus> responseStatusAnnotation = MergedAnnotations
                .from(error.getClass(), MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(ResponseStatus.class);

        HttpStatus errorStatus = determineHttpStatus(error, responseStatusAnnotation);

        //必须设置, 否则会报错, 因为 DefaultErrorWebExceptionHandler 的 renderErrorResponse 方法会获取此属性, 重新实现 DefaultErrorWebExceptionHandler也可.
        errorAttributes.put("status", errorStatus.value());
        errorAttributes.put("code", errorStatus.value());

        //html view用
        errorAttributes.put("timestamp", new Date());
        //html view 用
        errorAttributes.put("requestId", request.exchange().getRequest().getId());

        errorAttributes.put("error", errorStatus.getReasonPhrase());
        errorAttributes.put("exception", error.getClass().getName());

        return errorAttributes;
    }

    //从DefaultErrorWebExceptionHandler中复制过来的
    private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation<ResponseStatus> responseStatusAnnotation) {
        if (error instanceof ResponseStatusException) {
            return ((ResponseStatusException) error).getStatus();
        }
        return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(HttpStatus.INTERNAL_SERVER_ERROR);
    }

}

这样就可以了.

注意注意: 必须设置 errorAttributes.put("status", errorStatus.value()) , 否则会报错, 因为 DefaultErrorWebExceptionHandler 的 renderErrorResponse 方法会获取此属性. 除非你自己像方法一一样重新实现 DefaultErrorWebExceptionHandler.

然后在网关中访问一个不存在的服务, 即可看到效果.

curl 'http://127.0.0.1:8900/fundmain22/abc/gogogo?id=1000' --header 'Accept: application/json'
{"exception":"org.springframework.web.server.ResponseStatusException","path":"/fundmain22/abc/gogogo","code":404,"method":"GET","requestId":"094e53e5-1","message":"404 NOT_FOUND","error":"Not Found","status":404,"timestamp":"2021-08-09T11:07:44.106+0000"}

感谢网络上的各种文章...

到此这篇关于Spring Cloud Gateway自定义异常处理Exception Handler的文章就介绍到这了,更多相关Spring Cloud Gateway自定义异常处理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java ClassCastException异常解决方案

    ClassCastException是JVM在检测到两个类型间转换不兼容时引发的运行时异常.此类错误通常会终止用户请求.在执行任何子系统的应用程序代码时都有可能发生ClassCastException异常.通过转换,可以指示Java编译器将给定类型的变量作为另一种变量来处理.对基础类型和用户定义类型都可以转换.Java语言规范定义了允许的转换,其中大多数可在编译时进行验证.不过,某些转换还需要运行时验证.如果在此运行时验证过程中检测到不兼容,JVM就会引发ClassCastException异常

  • Java异常 Factory method'sqlSessionFactory'rew exception;ested exception is java.lang.NoSuchMethodError:

    springboot 引入mybatis-plus后报错: Factory method 'sqlSessionFactory' threw exception; nested exception is java.lang.NoSuchMethodError: com.baomidou.mybatisplus.entity.GlobalConfiguration.getWorkerId()Ljava/lang/Long; org.apache.ibatis.binding.BindingExce

  • 解析PHP中Exception异常机制

    异常的基本使用 当异常被抛出时,其后的代码不会继续执行,PHP 会尝试查找匹配的 "catch" 代码块. 如果异常没有被捕获,而且又没用使用 set_exception_handler() 作相应的处理的话,那么将发生一个严重的错误(致命错误),并且输出 "Uncaught Exception" (未捕获异常)的错误消息. 让我们尝试抛出一个异常,同时不去捕获它: <?php //create function with an exception funct

  • Java java.lang.InstantiationException异常案例详解

      java.lang.InstantiationException 是指不能实例化某个对象,一般在我们使用java反射机制去创建某个对象的时候实例化到了一个抽象类或者接口(java中抽象类和接口是不能被实例化),而今天我遇到的则是我在使用反射机制实例化某个持久类的时候爆出这个异常,后来发现是因为iBATIS在对象建立中,会使用不带参数的构造函数来建立对象,而自己的持久化类中含有带参数的构造方法,将默认无参构造方法覆盖,导致在实例化过程出现异常.所以在定义一个无参构造方法可解决. 异常 持久类没

  • java.lang.NullPointerException异常问题解决方案

    java.lang.NullPointerException异常原因是因为创建了一个引用类型的变量却没有指向任何对象而又去通过这个引用类型变量加点的形式去访问非静态的方法及属性. 给出三种情况, 第一种情况,在启动类中定义了引用类型变量,赋值为空: /** * 引用类型变量没有指向对象所引起的空指针异常 * @author Superhero * @version 2018年12月16日上午10:32:43 */ //图书类 class Books { private String name;

  • java.lang.NumberFormatException异常解决方案详解

    前言:        在做后台时用的jsp开发,在页面向controller传参时用String接收的参数,但是数据库实体中jies接收该参数时是int类型,做了一下强制转换,但是没有判断去空格,结果页面加载时就报500错误了. 错误截图: 在报错后注意分析报错信息,如上图提示在ShopController.java 的92行出错了,那么错误就很容易定位了,去看那里的代码. 错误关键字 java.lang.NumberFormatException 这句话明确告诉了我们是数字格式异常,接着后面有

  • 解决使用RestTemplate时报错RestClientException的问题

    目录 使用RestTemplate时报错RestClientException 这是自己封装的一个发送请求的方法 这是自定义的一个http信息Converter RestTemplate的错误处理 问题描述 ErrorHandler 解决办法 使用RestTemplate时报错RestClientException 这是自己封装的一个发送请求的方法 public Map<String, Object> sendRequest(Map<String, Object> body,Str

  • Java中Exception和Error的区别详解

    世界上存在永远不会出错的程序吗?也许这只会出现在程序员的梦中.随着编程语言和软件的诞生,异常情况就如影随形地纠缠着我们,只有正确的处理好意外情况,才能保证程序的可靠性. java语言在设计之初就提供了相对完善的异常处理机制,这也是java得以大行其道的原因之一,因为这种机制大大降低了编写和维护可靠程序的门槛.如今,异常处理机制已经成为现代编程语言的标配. 今天我要问你的问题是,请对比Exception和Error,另外,运行时异常与一般异常有什么区别? 典型回答 Exception和Error都

  • Spring Cloud Gateway自定义异常处理Exception Handler的方法小结

    版本: Spring Cloud 2020.0.3 常见的方法有 实现自己的 DefaultErrorWebExceptionHandler 或 仅实现ErrorAttributes. 方法1: ErrorWebExceptionHandler (仅供示意) 自定义一个 GlobalErrorAttributes: @Component public class GlobalErrorAttributes extends DefaultErrorAttributes{ @Override pub

  • Spring Cloud Gateway自定义异常处理Exception Handler

    版本: Spring Cloud 2020.0.3 常见的方法有 实现自己的 DefaultErrorWebExceptionHandler 或 仅实现ErrorAttributes. 方法1: ErrorWebExceptionHandler (仅供示意) 自定义一个 GlobalErrorAttributes: @Component public class GlobalErrorAttributes extends DefaultErrorAttributes{ @Override pub

  • 一文吃透Spring Cloud gateway自定义错误处理Handler

    目录 正文 AbstractErrorWebExceptionHandler isDisconnectedClientError方法 isDisconnectedClientErrorMessage方法: 小结 NestedExceptionUtils getRoutingFunction logError write 其他的方法 afterPropertiesSet renderDefaultErrorView renderErrorView DefaultErrorWebExceptionH

  • Spring Cloud Gateway全局异常处理的方法详解

    前言 Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式.Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等

  • Spring Cloud Gateway 默认的filter功能和执行顺序介绍

    目录 Spring Cloud Gateway 默认的filter功能和执行顺序 有效性 调试方法 filters(按执行顺序) spring cloud gateway之filter实战 1.filter的作用和生命周期 2.AddRequestHeader GatewayFilter Factory Spring Cloud Gateway 默认的filter功能和执行顺序 有效性 Spring Cloud Gateway 2.0.0.RELEASE 调试方法 新建一个GlobalFilte

  • Spring Cloud zuul自定义统一异常处理实现方法

    Zuul在springcloud微服务体系中提供filer和router功能,是微服务不可或缺的部分.filer处理默认实现的外还可以自定义进行授权.限流.安全校验等,router完全可以替代Nginx反向代理.Zuul异常处理就是由SendErrorFilter完成. 在我们应用过程我们发现使用默认的异常filter有两个问题不是很友好: 1.无法快速识别出是否是请求路由的服务超时还是没有任何可用节点,发生错误只能查看日志通过堆栈去定位: 2.无法兼容自定义的譬如{code:500,msg:"

  • Spring Cloud Gateway全局通用异常处理的实现

    为什么需要全局异常处理 在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回 // 摘至 spring cloud alibaba console 模块处理 @ControllerAdvice public class ConsoleExceptionHandler { @ExceptionHandler(AccessException.class) private ResponseEntity<String> handleAc

  • 阿里Sentinel支持Spring Cloud Gateway的实现

    1. 前言 4月25号,Sentinel 1.6.0 正式发布,带来 Spring Cloud Gateway 支持.控制台登录功能.改进的热点限流和注解 fallback 等多项新特性,该出手时就出手,紧跟时代潮流,昨天刚发布,今天我就要给大家分享下如何使用! 2. 介绍(本段来自Sentinel文档) Sentinel 1.6.0 引入了 Sentinel API Gateway Adapter Common 模块,此模块中包含网关限流的规则和自定义 API 的实体和管理逻辑: Gatewa

  • Spring Cloud Gateway 服务网关快速实现解析

    Spring Cloud Gateway 服务网关 API 主流网关有NGINX.ZUUL.Spring Cloud Gateway.Linkerd等:Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的.非阻塞式的 API.同时,它支持 websockets,和 Spring 框架紧密集成,用来代替服务网关Zuul,开发体验相对来说十分不错. Spring Cloud Gateway 是 Spring Cloud 微服务平台的一个子

  • Spring Cloud Gateway入门解读

    Spring Cloud Gateway介绍 前段时间刚刚发布了Spring Boot 2正式版,Spring Cloud Gateway基于Spring Boot 2,是Spring Cloud的全新项目,该项目提供了一个构建在Spring 生态之上的API网关,包括:Spring 5,Spring Boot 2和Project Reactor. Spring Cloud Gateway旨在提供一种简单而有效的途径来发送API,并为他们提供横切关注点,例如:安全性,监控/指标和弹性.当前最新的

随机推荐