Skip to content
Advertisement

JAX-RS LoggingFilter – Log request entities

I’m using a class implementing ClientRequestFilter

@Override
public void filter(ClientRequestContext requestContext) throws IOException {
    logger.trace(F_SEPARATOR);
    logger.trace(String.format(F_REQUEST, requestContext.getMethod(), requestContext.getUri()));
    requestContext.getHeaders()
                    .keySet()
                    .stream()
                    .sorted()
                    .forEach(key -> {
                        logger.trace(String.format(F_HEADER, key, requestContext.getHeaders().get(key)));
                    });
    if (requestContext.hasEntity()) {
        if(requestContext.getHeaders().get("Content-Type").get(0).toString().equals("multipart/form-data")) {
            FormDataMultiPart formDataMultiPart = (FormDataMultiPart) requestContext.getEntity();
            logger.trace(String.format(F_PART_NUMBER, formDataMultiPart.getBodyParts().size()));
            AtomicInteger index = new AtomicInteger(1);
            formDataMultiPart.getBodyParts().stream()
                    .forEach(bodyPart -> {
                        logger.trace(String.format(F_PART + F_PART_CONTENT_TYPE, index.get(), requestContext.getMediaType().toString()));
                        if(bodyPart.getMediaType().toString().equals("text/xml")) {
                            StreamDataBodyPart streamDataBodyPart = (StreamDataBodyPart) bodyPart;
                            String part = new BufferedReader(
                                    new InputStreamReader(streamDataBodyPart.getStreamEntity(), StandardCharsets.UTF_8))
                                    .lines()
                                    .collect(Collectors.joining("n"));
                            logger.trace(String.format(F_PART + F_PART_CONTENT, index.get(), part));
                        }
                        index.getAndIncrement();
                    });
        }
    }
    requestContext.setProperty(PROPERTY_NANOS, System.nanoTime());
}

It is working fine except that after being logged the bodypart stream seems to be consumed and is not sent with the request. How can I do to display the bodypart stream and make it again available for the request itself ?

For the response it was the same problem and I managed to have it working with

    if (responseContext.hasEntity()) {
        InputStream entityStream = responseContext.getEntityStream();
        byte[] bytes = IOUtils.toByteArray(entityStream);
        responseContext.setEntityStream(new ByteArrayInputStream(bytes));
        String entity = new String(bytes);
        logger.trace(String.format(F_ENTITY, entity));
    }

Solution 1 : buffuring the stream.

@Override
public void filter(ClientRequestContext requestContext) throws IOException {
    ClientRequest clientRequest = (ClientRequest) requestContext;
    clientRequest.enableBuffering();
    logger.trace(F_SEPARATOR);
    logger.trace(String.format(F_REQUEST, clientRequest.getMethod(), clientRequest.getUri()));
    clientRequest.getHeaders()
                    .keySet()
                    .stream()
                    .sorted()
                    .forEach(key -> {
                        logger.trace(String.format(F_HEADER, key, clientRequest.getHeaders().get(key)));
                    });
    if (clientRequest.hasEntity()) {
        if(clientRequest.getHeaders().get("Content-Type").get(0).toString().equals("multipart/form-data")) {
            FormDataMultiPart formDataMultiPart = (FormDataMultiPart) clientRequest.getEntity();
            logger.trace(String.format(F_PART_NUMBER, formDataMultiPart.getBodyParts().size()));
            AtomicInteger index = new AtomicInteger(1);
            formDataMultiPart.getBodyParts().stream()
                    .forEach(bodyPart -> {
                        logger.trace(String.format(F_PART + F_PART_CONTENT_TYPE, index.get(), clientRequest.getMediaType().toString()));
                        if(bodyPart.getMediaType().toString().equals("text/xml")) {
                            StreamDataBodyPart streamDataBodyPart = (StreamDataBodyPart) bodyPart;
                            String part = new BufferedReader(
                                    new InputStreamReader(streamDataBodyPart.getStreamEntity(), StandardCharsets.UTF_8))
                                    .lines()
                                    .collect(Collectors.joining("n"));
                            logger.trace(String.format(F_PART + F_PART_CONTENT, index.get(), part));
                        }
                        index.getAndIncrement();
                    });
        }
    }
    clientRequest.setProperty(PROPERTY_NANOS, System.nanoTime());
}

But it is still not working.

Advertisement

Answer

My working solution

@Override
public void filter(ClientRequestContext requestContext) throws IOException {
    ClientRequest clientRequest = (ClientRequest) requestContext;
    clientRequest.enableBuffering();
    logger.trace(F_SEPARATOR);
    logger.trace(String.format(F_REQUEST, clientRequest.getMethod(), clientRequest.getUri()));
    clientRequest.getHeaders()
                    .keySet()
                    .stream()
                    .sorted()
                    .forEach(key -> {
                        logger.trace(String.format(F_HEADER, key, clientRequest.getHeaders().get(key)));
                    });
    if (clientRequest.hasEntity()) {
        if(clientRequest.getHeaders().get("Content-Type").get(0).toString().equals("multipart/form-data")) {
            FormDataMultiPart formDataMultiPart = (FormDataMultiPart) clientRequest.getEntity();
            logger.trace(String.format(F_PART_NUMBER, formDataMultiPart.getBodyParts().size()));
            AtomicInteger index = new AtomicInteger(1);
            formDataMultiPart.getBodyParts().stream()
                    .forEach(bodyPart -> {
                        logger.trace(String.format(F_PART + F_PART_CONTENT_TYPE, index.get(), bodyPart.getMediaType().toString()));
                        if(bodyPart.getMediaType().toString().equals("text/xml")) {
                            byte[] bytes = null;
                            try {
                                bytes = IOUtils.toByteArray(((StreamDataBodyPart)bodyPart).getStreamEntity());
                                logger.trace(String.format(F_PART + F_PART_CONTENT, index.get(), new String(bytes)));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            ((StreamDataBodyPart) bodyPart).setStreamEntity(new ByteArrayInputStream(bytes));
                        }
                        index.getAndIncrement();
                    });
        }
    }
    clientRequest.setProperty(PROPERTY_NANOS, System.nanoTime());
}
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement