Skip to content

ClientResponse's body ignored on UnsupportedMediaTypeException [SPR-17054] #21592

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Jul 17, 2018 · 0 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Jul 17, 2018

Denys Ivano opened SPR-17054 and commented

When remote service responses with Content-Type that can't be read by HttpMessageReader, an instance of UnsupportedMediaTypeException is being thrown (see BodyExtractors.readWithMessageReaders()). But ClientResponse's body is being ignored in this case.

From ClientResponse's Javadoc:

* <p><strong>NOTE:</strong> When given access to a {@link ClientResponse},
* through the {@code WebClient}
* {@link WebClient.RequestHeadersSpec#exchange() exchange()} method,
* you must always use one of the body or toEntity methods to ensure resources
* are released and avoid potential issues with HTTP connection pooling.
* You can use {@code bodyToMono(Void.class)} if no response content is
* expected. However keep in mind that if the response does have content, the
* connection will be closed and will not be placed back in the pool.

So in order to release resources and avoid potential issues with HTTP connection pool, the response body must be consumed.

I've created a test that reproduces this issue:

@Test
public void shouldConsumeBodyOnUnsupportedMediaTypeException() {
    AtomicBoolean bodyConsumed = new AtomicBoolean();
    ExchangeFunction exchangeFunction = mock(ExchangeFunction.class);
    ClientResponse response = ClientResponse.create(HttpStatus.OK)
            .header(HttpHeaders.CONTENT_TYPE, "application/unknown")
//                .header(HttpHeaders.CONTENT_TYPE, "application/json")
            .body(Flux.defer(() -> {
                DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                return Flux.just("{\"name\": \"Hello World!\"}").
                        map(s -> {
                            bodyConsumed.set(true);
                            byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
                            return dataBufferFactory.wrap(bytes);
                        });
            }))
            .build();

    when(exchangeFunction.exchange(any())).thenReturn(Mono.just(response));

    WebClient webClient = WebClient.builder()
            .exchangeFunction(exchangeFunction)
            .build();

    Mono<String> result = webClient.get()
            .retrieve()
            .bodyToMono(TestResponse.class)
            .map(TestResponse::getName);

    StepVerifier.create(result)
            .expectError(UnsupportedMediaTypeException.class)
//                .expectNext("Hello World!")
//                .expectComplete()
            .verify(Duration.ZERO);

    assertTrue("Response body wasn't consumed", bodyConsumed.get());
}

private static class TestResponse {

    private String name;

    public String getName() {
        return name;
    }

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

Issue Links:

Referenced from: commits a410d90, d0ada56

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

2 participants