Avoided repeated creation of ReadOnlyHttpHeaders wrapper

See gh-24680
This commit is contained in:
Rossen Stoyanchev
2020-05-08 14:07:30 +01:00
parent 3276f81851
commit df99889aa6
10 changed files with 99 additions and 62 deletions

View File

@@ -234,29 +234,28 @@ class DefaultClientResponse implements ClientResponse {
private class DefaultHeaders implements Headers {
private HttpHeaders delegate() {
return response.getHeaders();
}
private final HttpHeaders httpHeaders =
HttpHeaders.readOnlyHttpHeaders(response.getHeaders());
@Override
public OptionalLong contentLength() {
return toOptionalLong(delegate().getContentLength());
return toOptionalLong(this.httpHeaders.getContentLength());
}
@Override
public Optional<MediaType> contentType() {
return Optional.ofNullable(delegate().getContentType());
return Optional.ofNullable(this.httpHeaders.getContentType());
}
@Override
public List<String> header(String headerName) {
List<String> headerValues = delegate().get(headerName);
List<String> headerValues = this.httpHeaders.get(headerName);
return (headerValues != null ? headerValues : Collections.emptyList());
}
@Override
public HttpHeaders asHttpHeaders() {
return HttpHeaders.readOnlyHttpHeaders(delegate());
return this.httpHeaders;
}
private OptionalLong toOptionalLong(long value) {

View File

@@ -265,8 +265,8 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
.map(filter -> filter.apply(exchange))
.orElse(exchange) : exchange);
return new DefaultWebClient(filteredExchange, initUriBuilderFactory(),
this.defaultHeaders != null ? unmodifiableCopy(this.defaultHeaders) : null,
this.defaultCookies != null ? unmodifiableCopy(this.defaultCookies) : null,
this.defaultHeaders != null ? HttpHeaders.readOnlyHttpHeaders(this.defaultHeaders) : null,
this.defaultCookies != null ? HttpHeaders.readOnlyHttpHeaders(this.defaultCookies) : null,
this.defaultRequest, new DefaultWebClientBuilder(this));
}
@@ -308,10 +308,6 @@ final class DefaultWebClientBuilder implements WebClient.Builder {
return factory;
}
private static HttpHeaders unmodifiableCopy(HttpHeaders headers) {
return HttpHeaders.readOnlyHttpHeaders(headers);
}
private static <K, V> MultiValueMap<K, V> unmodifiableCopy(MultiValueMap<K, V> map) {
return CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<>(map));
}

View File

@@ -260,61 +260,60 @@ class DefaultServerRequest implements ServerRequest {
private class DefaultHeaders implements Headers {
private HttpHeaders delegate() {
return request().getHeaders();
}
private final HttpHeaders httpHeaders =
HttpHeaders.readOnlyHttpHeaders(request().getHeaders());
@Override
public List<MediaType> accept() {
return delegate().getAccept();
return this.httpHeaders.getAccept();
}
@Override
public List<Charset> acceptCharset() {
return delegate().getAcceptCharset();
return this.httpHeaders.getAcceptCharset();
}
@Override
public List<Locale.LanguageRange> acceptLanguage() {
return delegate().getAcceptLanguage();
return this.httpHeaders.getAcceptLanguage();
}
@Override
public OptionalLong contentLength() {
long value = delegate().getContentLength();
long value = this.httpHeaders.getContentLength();
return (value != -1 ? OptionalLong.of(value) : OptionalLong.empty());
}
@Override
public Optional<MediaType> contentType() {
return Optional.ofNullable(delegate().getContentType());
return Optional.ofNullable(this.httpHeaders.getContentType());
}
@Override
public InetSocketAddress host() {
return delegate().getHost();
return this.httpHeaders.getHost();
}
@Override
public List<HttpRange> range() {
return delegate().getRange();
return this.httpHeaders.getRange();
}
@Override
public List<String> header(String headerName) {
List<String> headerValues = delegate().get(headerName);
List<String> headerValues = this.httpHeaders.get(headerName);
return (headerValues != null ? headerValues : Collections.emptyList());
}
@Override
public HttpHeaders asHttpHeaders() {
return HttpHeaders.readOnlyHttpHeaders(delegate());
return this.httpHeaders;
}
@Override
public String toString() {
return delegate().toString();
return this.httpHeaders.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,6 +60,8 @@ public class DefaultClientResponseTests {
private ClientHttpResponse mockResponse;
private final HttpHeaders httpHeaders = new HttpHeaders();
private ExchangeStrategies mockExchangeStrategies;
private DefaultClientResponse defaultClientResponse;
@@ -68,6 +70,7 @@ public class DefaultClientResponseTests {
@BeforeEach
public void createMocks() {
mockResponse = mock(ClientHttpResponse.class);
given(mockResponse.getHeaders()).willReturn(this.httpHeaders);
mockExchangeStrategies = mock(ExchangeStrategies.class);
defaultClientResponse = new DefaultClientResponse(mockResponse, mockExchangeStrategies, "", "", () -> null);
}
@@ -91,7 +94,6 @@ public class DefaultClientResponseTests {
@Test
public void header() {
HttpHeaders httpHeaders = new HttpHeaders();
long contentLength = 42L;
httpHeaders.setContentLength(contentLength);
MediaType contentType = MediaType.TEXT_PLAIN;
@@ -233,7 +235,6 @@ public class DefaultClientResponseTests {
= factory.wrap(ByteBuffer.wrap("foo".getBytes(StandardCharsets.UTF_8)));
Flux<DataBuffer> body = Flux.just(dataBuffer);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
given(mockResponse.getHeaders()).willReturn(httpHeaders);
given(mockResponse.getStatusCode()).willThrow(new IllegalArgumentException("999"));
@@ -293,13 +294,12 @@ public class DefaultClientResponseTests {
}
@Test
public void toEntityListWithUnknownStatusCode() throws Exception {
public void toEntityListWithUnknownStatusCode() {
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
DefaultDataBuffer dataBuffer =
factory.wrap(ByteBuffer.wrap("foo".getBytes(StandardCharsets.UTF_8)));
Flux<DataBuffer> body = Flux.just(dataBuffer);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
given(mockResponse.getHeaders()).willReturn(httpHeaders);
given(mockResponse.getStatusCode()).willThrow(new IllegalArgumentException("999"));
@@ -321,8 +321,7 @@ public class DefaultClientResponseTests {
@Test
public void toEntityListTypeReference() {
DefaultDataBufferFactory factory = new DefaultDataBufferFactory();
DefaultDataBuffer dataBuffer =
factory.wrap(ByteBuffer.wrap("foo".getBytes(StandardCharsets.UTF_8)));
DefaultDataBuffer dataBuffer = factory.wrap(ByteBuffer.wrap("foo".getBytes(StandardCharsets.UTF_8)));
Flux<DataBuffer> body = Flux.just(dataBuffer);
mockTextPlainResponse(body);
@@ -332,8 +331,7 @@ public class DefaultClientResponseTests {
given(mockExchangeStrategies.messageReaders()).willReturn(messageReaders);
ResponseEntity<List<String>> result = defaultClientResponse.toEntityList(
new ParameterizedTypeReference<String>() {
}).block();
new ParameterizedTypeReference<String>() {}).block();
assertThat(result.getBody()).isEqualTo(Collections.singletonList("foo"));
assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(result.getStatusCodeValue()).isEqualTo(HttpStatus.OK.value());
@@ -342,9 +340,7 @@ public class DefaultClientResponseTests {
private void mockTextPlainResponse(Flux<DataBuffer> body) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.TEXT_PLAIN);
given(mockResponse.getHeaders()).willReturn(httpHeaders);
given(mockResponse.getStatusCode()).willReturn(HttpStatus.OK);
given(mockResponse.getRawStatusCode()).willReturn(HttpStatus.OK.value());
given(mockResponse.getBody()).willReturn(body);