在Spring Cloud网关过滤器中抛出自定义运行时异常

5
我们正在使用Spring Boot 2和reactive WebFlux模块的Spring Cloud Gateway。
其中一个路由添加了认证过滤器。现在,如果我们抛出一个具有特定状态码的RuntimeException,它实际上无法被捕获。
之前这个认证检查是Spring中的HandlerInterceptor的一部分,但是现在我们不能与WebFlux一起使用web模块(来自Spring cloud gateway的冲突)。
示例:
@Override
public GatewayFilter apply(Object config) {
   ServerHttpRequest httpRequest = exchange.getRequest();
   if(!someUtil.validRequest(httpRequest) {
          throw new RuntimeException("Throw 401 Unauthorized with Custom error code and message");
   }
}

目前,实际响应始终会给出一个500内部服务器错误。这是从何处发出的?我们能否在这里获取来自过滤器的错误信息?

2个回答

2

您可以实现自定义错误处理程序,这里是Spring Boot文档

或者您可以简单地抛出ResponseStatusException。默认的错误处理程序将呈现特定的状态。


抛出带有自定义HTTP状态码的 ResponseStatusException 对我来说是有效的,但它仍然绕过了 Spring Boot 的 @ControllerAdvice 控制器。 - Tim Biegeleisen

-1
请记住,截至撰写本文时,spring-cloud-gateway使用的是Spring Framework WebFlux。这意味着方法会有所不同。您可以像下面显示的那样在过滤器中获取异常。
像这样声明一个异常:
public class UnauthorisedException extends ResponseStatusException {

    public UnauthorisedException(HttpStatusCode status) {
        super(status);
    }

    public UnauthorisedException(HttpStatusCode status, String reason) {
        super(status, reason);
    }

}

注意:异常扩展了ResponseStatusException。

ControllerAdvice类可以按以下方式实现:

@ControllerAdvice
public class MyErrorWebExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(UnauthorisedException.class)
    public Mono<ServerResponse> handleIllegalState(ServerWebExchange exchange, UnauthorisedException exc) {
         exchange.getAttributes().putIfAbsent(ErrorAttributes.ERROR_ATTRIBUTE, exc);
return ServerResponse.from(ErrorResponse.builder(exc,HttpStatus.FORBIDDEN,exc.getMessage()).build());
    }

}

在你的过滤器中,现在可以按照以下方式实现apply方法:
public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
                if (request.getHeaders().get("token") == null){ //test is an example
                    throw new UnauthorisedException(HttpStatus.FORBIDDEN, "Not Authorised from Gateway");
                }
            ServerHttpRequest.Builder builder = request.mutate();
            return chain.filter(exchange.mutate().request(builder.build()).build());
        };
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接