springcloud-gateway 异常处理

CustomErrorWebFluxAutoConfiguration


@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
@ConditionalOnClass(WebFluxConfigurer.class)
@AutoConfigureBefore(WebFluxAutoConfiguration.class)
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class CustomErrorWebFluxAutoConfiguration {

    private final ServerProperties serverProperties;

    private final ApplicationContext applicationContext;

    private final ResourceProperties resourceProperties;

    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public CustomErrorWebFluxAutoConfiguration(ServerProperties serverProperties,
                                               ResourceProperties resourceProperties,
                                               ObjectProvider<ViewResolver> viewResolversProvider,
                                               ServerCodecConfigurer serverCodecConfigurer,
                                               ApplicationContext applicationContext) {
        this.serverProperties = serverProperties;
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
        this.viewResolvers = viewResolversProvider.orderedStream()
                .collect(Collectors.toList());
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @ConditionalOnMissingBean(value = ErrorWebExceptionHandler.class,
            search = SearchStrategy.CURRENT)
    @Order(-1)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
    	//此处添加自定义异常处理
        JsonErrorWebExceptionHandler exceptionHandler = new JsonErrorWebExceptionHandler(
                errorAttributes,
                resourceProperties,
                this.serverProperties.getError(),
                applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }

    @Bean
    @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
    public DefaultErrorAttributes errorAttributes() {
        return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException());
    }

}

JsonErrorWebExceptionHandler

public class JsonErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {

    public JsonErrorWebExceptionHandler(ErrorAttributes errorAttributes,
                                        ResourceProperties resourceProperties,
                                        ErrorProperties errorProperties,
                                        ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }

    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
    
        int code = 500;
        String msg;
        Throwable error = super.getError(request);
        System.out.println(error);
        if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) {
            code = 404;
            msg = error.getMessage();
        }
        if (error instanceof org.springframework.web.server.ResponseStatusException) {
            code = ((ResponseStatusException) error).getStatus().value();
            msg = error.getMessage();
        }
        msg = error.getMessage();
        Map<String, Object> errorAttributes = new HashMap<>(8);
        errorAttributes.put("message", error.getMessage());
        errorAttributes.put("code", code);
        errorAttributes.put("method", request.methodName());
        errorAttributes.put("path", request.path());
        return errorAttributes;
    }

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    @Override
    protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
        int statusCode = (int) errorAttributes.get("code");
        System.out.println(statusCode);
        return HttpStatus.valueOf(statusCode);
    }

}

经测试发现,当下方微服务未启动时,异常类型为ResponseStatusException,并非NotFoundException;

测试结果

在这里插入图片描述

Spring Cloud Gateway 提供了一种全局异常处理机制,它允许你在整个网关链路中统一管理和捕获错误。通过使用 `GlobalExceptionHandler` 或自定义拦截器,你可以配置如何处理来自下游服务的响应失败、路由错误或其他非预期的状况。 通常,全局异常处理的过程包括以下几个步骤: 1. **创建全局异常处理器**:在 Spring Boot 应用中,你可以创建一个实现了 `GlobalExceptionHandler` 接口的类,并覆盖其 `handle` 方法。这个方法接收 `WebExchange` 和 `Throwable` 参数,你可以在这里定制错误处理逻辑,如记录日志、返回统一的错误响应等。 ```java @Component public class GlobalExceptionHandler implements GlobalExceptionHandler { @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { // 捕获异常并返回适当的响应 return handleException(exchange, new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage())); } } ``` 2. **应用配置**:在 Gateway 的配置中启用全局异常处理,并指定你的全局处理器类。例如,在 YAML 配置中添加如下内容: ```yaml spring: cloud: gateway: global-error-handler: com.example.GlobalExceptionHandler ``` 3. **错误响应处理**:`handleException` 方法可以根据需要决定返回何种状态码和错误信息给客户端。常见的做法是返回一个统一的 JSON 格式,比如包含错误码和描述的消息。 当你设置好全局异常处理后,无论内部服务出现何种类型的异常,Spring Cloud Gateway 都会按照你设定的方式进行处理,提供一个一致的服务响应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值