Skip to content

UnsupportedOperationException with BufferingClientHttpRequestFactory in HttpComponentsClientHttpRequest body #35284

@mlasotaa

Description

@mlasotaa

This issue is related to #32023.
Following the recommendation there, I added BufferingClientHttpRequestFactory to my RestTemplate, but it didn’t change anything.

`

@Bean
public RestTemplate restTemplate() {
    CloseableHttpClient httpClient = HttpClients.custom()
            .addRequestInterceptorLast((HttpRequest request,
                                        EntityDetails entityDetails,
                                        HttpContext context) -> {

                HttpEntity httpEntity = ((BasicClassicHttpRequest) request).getEntity();
                try {
                    // FIXME – After upgrading Spring from 5.7.x to 6.2.9, HttpEntity#getContent is no longer
                    // implemented and now consistently throws an exception (even when the request is wrapped
                    // in a BufferingClientHttpRequestFactory). This breaks our internal request-body logging.
                    // Current workaround: cache the body manually before this point so that HttpEntity is
                    // backed by non-null content.
                    System.out.println("request body " + EntityUtils.toString(httpEntity));
                } catch (UnsupportedOperationException e) {
                    System.out.println("request body workaround" + EntityUtils.toString(cacheHttpEntity(httpEntity)));
                    e.printStackTrace();
                }
            })
            .build();

    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
    return new RestTemplate(new BufferingClientHttpRequestFactory(factory));
}

`

My Workaround

`

// Temporal solution

private static HttpEntity cacheHttpEntity(HttpEntity entity) {
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        entity.writeTo(baos);
        return new ByteArrayEntity(
                baos.toByteArray(),
                ContentType.parse(entity.getContentType()));
    } catch (IOException exception) {
        return entity;
    }
}`

I'm leaving a link to my GitHub repository with the entire demo project.
https://github.com/mlasotaa/spring-6-2-9-rest-template/blob/master/src/main/java/com/example/demo/RestTemplateConfiguration.java

Is there anything else I can do to get access to the body in my custom logger without additional creating ByteArrayEntity?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions