Facing issue while trying to log request using ServerHttpRequestDecorator in Filter

179 Views Asked by At

I am trying to use ServerHttpRequestDecorator and ServerHttpResponseDecorator to log the request and response bodies. I am facing a strange problem, the doNext method of the ServerHttpRequestDecorator is being called twice and due to that whole payload is not getting logged, its being logged in two parts

Full payload:

{
    "id":"789654",
    "communication":"email",
    "document":[
        {
            "identificationNumber":"4563217",
            "expiryDate":"04042024"
        }
    ],
    "firstName":"KADE",
    "lastName":"NESSLEIN",
    "clientType": "EXISTING"
}

Incomplete payload Part 1:

{ "id":"789654", "communication":"email", "document":[ { "identificationNumber":"4563217", "expiryDat

Incomplete payload Part 2:

e":"04042024" } ], "firstName":"KADE", "lastName":"NESSLEIN", "clientType": "EXISTING" }

ServerHttpRequestDecorator and ServerHttpResponseDecorator code

private ServerHttpRequest getDecoratedRequest(ServerHttpRequest request) {

        return new ServerHttpRequestDecorator(request) {
            @Override
            public Flux<DataBuffer> getBody() {

                log.debug("requestId: {}, method: {} , url: {}", request.getId(), request.getMethodValue(), request.getURI());
                return super.getBody().publishOn(Schedulers.boundedElastic()).doOnNext(dataBuffer -> {

                    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {

                        Channels.newChannel(byteArrayOutputStream).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
                        String requestBody = IOUtils.toString(byteArrayOutputStream.toByteArray(), StandardCharsets.UTF_8.toString());//MODIFY REQUEST and Return the Modified request
                        log.debug("for requestId: {}, request body :{}", request.getId(), requestBody);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                    }
                });
            }
        };
    }
private ServerHttpResponseDecorator getDecoratedResponse(String path, ServerHttpResponse response, ServerHttpRequest request, DataBufferFactory dataBufferFactory) {
        return new ServerHttpResponseDecorator(response) {

            @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 -> {

                        DefaultDataBuffer joinedBuffers = new DefaultDataBufferFactory().join(dataBuffers);
                        byte[] content = new byte[joinedBuffers.readableByteCount()];
                        joinedBuffers.read(content);
                         String responseBody = new String(content, StandardCharsets.UTF_8);//MODIFY RESPONSE and Return the Modified response
                        log.debug("requestId: {}, method: {}, url: {}, \nresponse body :{}", request.getId(), request.getMethodValue(), request.getURI(), responseBody);

                        return dataBufferFactory.wrap(responseBody.getBytes());
                    })).onErrorResume(err -> {

                        log.error("error while decorating Response: {}",err.getMessage());
                        return Mono.empty();
                    });

                }
                return super.writeWith(body);
            }
        };
    }

Sometimes payload is being logged completely but sometimes its broken and being logged in parts. Kindly let me know how I can fix it to get the whole payload getting logged at all times.

Many thanks, Sandeep

I am expecting to have the full payload logged at all times.

0

There are 0 best solutions below