Return response from Spring cloud gateway filter without forwarding to next filter/service

22 Views Asked by At

i want to return custom response from spring cloud gateway custom filter without forwarding the request to next filter/service. i have written following code.

@Component public class AuthFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {



    final ServerHttpRequest request = exchange.getRequest();
    Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
    
    String secretKey=null;
   if (request != null) {

       String serviceId = util.getServiceId(route.getUri().getAuthority());
        if (StringUtils.isEmpty(serviceId)) {
           serviceId = route.getUri().getAuthority();
        }
     
        if (this.externalApis.contains(serviceId)) {
          
             return DataBufferUtils.join(exchange.getRequest().getBody())
                    .flatMap(dataBuffer -> {
                                DataBufferUtils.retain(dataBuffer);
                                Flux<DataBuffer> cachedFlux = Flux
                                        .defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));
                                ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
                                        exchange.getRequest()) {
                                    @Override
                                    public Flux<DataBuffer> getBody() {
                                        return cachedFlux;
                                    }

                                };

                                exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);
                        System.out.println(gatewayUtil.toRaw(cachedFlux));

                        Response responseObject=  runApi(exchange,chain);
                        ServerHttpResponseDecorator serverHttpResponseDecorator = gatewayUtil.customResponse(exchange, responseObject);
                  
                        return chain.filter(exchange.mutate().request(mutatedRequest)
                                .response(gatewayUtil.customResponse(exchange,responseObject)).build());
                    });


        }
        }

and the response object created as follows

public ServerHttpResponseDecorator customResponse(ServerWebExchange exchange,Object responseObj) {

    ServerHttpResponse originalResponse = exchange.getResponse();

    return new ServerHttpResponseDecorator(originalResponse) {
        HttpHeaders headers = new HttpHeaders();
        DataBufferFactory bufferFactory = originalResponse.bufferFactory();


        @Override
        public Mono<Void> writeWith(final Publisher<? extends DataBuffer> body) {

            if (body instanceof Flux) {

                Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;

                return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                    return bufferFactory.wrap("this is external".getBytes());

                }).switchIfEmpty(Flux.defer(() -> {

                    System.out.println("Write to database here");
                    return Flux.just();
                }))).onErrorResume(err -> {
                    // log.error("error while decorating Response: {}", err.getMessage());
                    return Mono.empty();
                });

            }


            else {
                System.out.println("2000000000");
            }
            return super.writeWith(body);
        }
    };

}

i want to return customer response back to client. please provide me a solution.

0

There are 0 best solutions below