Отправить ответ об ошибке из предварительного фильтра непосредственно из Spring Gateway

#spring-webflux #spring-cloud-gateway

#spring-webflux #spring-cloud-gateway

Вопрос:

Я использую Spring Gateway с приложением Spring WebFlux. В моем случае мне нужно вернуть HTTP 417 error, если определенные критерии не выполнены, прежде чем вызывать какую-либо службу ниже по потоку. По какой-то причине он не возвращает ошибку; на самом деле он ничего не возвращает.. запрос просто висит. Это мой код.

 @Component
public class GlobalGatewayPreFilter extends AbstractGatewayFilterFactory<GlobalGatewayPreFilter.Config> {

    public GlobalGatewayPreFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> exchange
                .getPrincipal()
                .filter(principal -> principal instanceof UserAuthenticationToken)
                .cast(UserAuthenticationToken.class)
                .filter(token -> (token.getUser().isVerified()))
                .defaultIfEmpty(setErrorResponse(exchange)).flatMap(chain::filter);
    }

    private ServerWebExchange setErrorResponse(ServerWebExchange exchange) {
        exchange.getResponse().setStatusCode(HttpStatus.EXPECTATION_FAILED);
        exchange.getResponse().setComplete();
        return exchange;
    }

    public static class Config {
        private String name;

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}
 

Есть ли какой-нибудь способ это исправить?

Ответ №1:

Хорошо, я смог решить эту проблему, используя следующее. Я публикую здесь с надеждой, что некоторые из них выиграют от этого.

 @Component
public class GlobalGatewayPreFilter extends AbstractGatewayFilterFactory<GlobalGatewayPreFilter.Config> {

    public GlobalGatewayPreFilter() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> exchange
                .getPrincipal()
                .filter(principal -> principal instanceof UserAuthenticationToken)
                .cast(UserAuthenticationToken.class)
                .filter(token -> (token.getUser().isVerified()))
                .switchIfEmpty(Mono.defer(() -> setErrorResponse(exchange.getResponse()).setComplete().then(Mono.empty())))
                .flatMap(chain::filter);
    }

    private ServerHttpResponse setErrorResponse(ServerHttpResponse serverHttpResponse) {
        serverHttpResponse.setStatusCode(HttpStatus.EXPECTATION_FAILED);
        return serverHttpResponse;
    }

    public static class Config {
        private String name;

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}