1717package org .springframework .boot .test .web .client ;
1818
1919import java .io .IOException ;
20- import java .lang .reflect .Field ;
2120import java .net .URI ;
2221import java .util .Arrays ;
2322import java .util .HashSet ;
2423import java .util .Map ;
2524import java .util .Set ;
26- import java .util .function .Supplier ;
2725
2826import org .apache .http .client .HttpClient ;
2927import org .apache .http .client .config .CookieSpecs ;
3634import org .apache .http .protocol .HttpContext ;
3735import org .apache .http .ssl .SSLContextBuilder ;
3836
39- import org .springframework .beans .BeanInstantiationException ;
40- import org .springframework .beans .BeanUtils ;
41- import org .springframework .boot .web .client .BasicAuthentication ;
42- import org .springframework .boot .web .client .BasicAuthenticationClientHttpRequestFactory ;
43- import org .springframework .boot .web .client .ClientHttpRequestFactorySupplier ;
4437import org .springframework .boot .web .client .RestTemplateBuilder ;
4538import org .springframework .boot .web .client .RootUriTemplateHandler ;
4639import org .springframework .core .ParameterizedTypeReference ;
4942import org .springframework .http .HttpMethod ;
5043import org .springframework .http .RequestEntity ;
5144import org .springframework .http .ResponseEntity ;
52- import org .springframework .http .client .AbstractClientHttpRequestFactoryWrapper ;
5345import org .springframework .http .client .ClientHttpRequestFactory ;
5446import org .springframework .http .client .ClientHttpResponse ;
5547import org .springframework .http .client .HttpComponentsClientHttpRequestFactory ;
56- import org .springframework .http .client .InterceptingClientHttpRequestFactory ;
5748import org .springframework .util .Assert ;
58- import org .springframework .util .ReflectionUtils ;
5949import org .springframework .web .client .DefaultResponseErrorHandler ;
6050import org .springframework .web .client .RequestCallback ;
6151import org .springframework .web .client .ResponseExtractor ;
8979 */
9080public class TestRestTemplate {
9181
92- private final RestTemplate restTemplate ;
82+ private final RestTemplateBuilder builder ;
9383
9484 private final HttpClientOption [] httpClientOptions ;
9585
86+ private final RestTemplate restTemplate ;
87+
9688 /**
9789 * Create a new {@link TestRestTemplate} instance.
9890 * @param restTemplateBuilder builder used to configure underlying
@@ -124,64 +116,30 @@ public TestRestTemplate(String username, String password,
124116
125117 /**
126118 * Create a new {@link TestRestTemplate} instance with the specified credentials.
127- * @param restTemplateBuilder builder used to configure underlying
128- * {@link RestTemplate}
119+ * @param builder builder used to configure underlying {@link RestTemplate}
129120 * @param username the username to use (or {@code null})
130121 * @param password the password (or {@code null})
131122 * @param httpClientOptions client options to use if the Apache HTTP Client is used
132123 * @since 2.0.0
133124 */
134- public TestRestTemplate (RestTemplateBuilder restTemplateBuilder , String username ,
135- String password , HttpClientOption ... httpClientOptions ) {
136- this ((restTemplateBuilder != null ) ? restTemplateBuilder .build () : null , username ,
137- password , httpClientOptions );
138- }
139-
140- private TestRestTemplate (RestTemplate restTemplate , String username , String password ,
125+ public TestRestTemplate (RestTemplateBuilder builder , String username , String password ,
141126 HttpClientOption ... httpClientOptions ) {
142- Assert .notNull (restTemplate , "RestTemplate must not be null" );
127+ Assert .notNull (builder , "Builder must not be null" );
128+ this .builder = builder ;
143129 this .httpClientOptions = httpClientOptions ;
144- if (getRequestFactoryClass (restTemplate )
145- .isAssignableFrom (HttpComponentsClientHttpRequestFactory .class )) {
146- restTemplate .setRequestFactory (
147- new CustomHttpComponentsClientHttpRequestFactory (httpClientOptions ));
148- }
149- addAuthentication (restTemplate , username , password );
150- restTemplate .setErrorHandler (new NoOpResponseErrorHandler ());
151- this .restTemplate = restTemplate ;
152- }
153-
154- private Class <? extends ClientHttpRequestFactory > getRequestFactoryClass (
155- RestTemplate restTemplate ) {
156- return getRequestFactory (restTemplate ).getClass ();
157- }
158-
159- private ClientHttpRequestFactory getRequestFactory (RestTemplate restTemplate ) {
160- ClientHttpRequestFactory requestFactory = restTemplate .getRequestFactory ();
161- while (requestFactory instanceof InterceptingClientHttpRequestFactory
162- || requestFactory instanceof BasicAuthenticationClientHttpRequestFactory ) {
163- requestFactory = unwrapRequestFactory (
164- ((AbstractClientHttpRequestFactoryWrapper ) requestFactory ));
130+ if (httpClientOptions != null ) {
131+ ClientHttpRequestFactory requestFactory = builder .buildRequestFactory ();
132+ if (requestFactory instanceof HttpComponentsClientHttpRequestFactory ) {
133+ builder = builder .requestFactory (
134+ () -> new CustomHttpComponentsClientHttpRequestFactory (
135+ httpClientOptions ));
136+ }
165137 }
166- return requestFactory ;
167- }
168-
169- private ClientHttpRequestFactory unwrapRequestFactory (
170- AbstractClientHttpRequestFactoryWrapper requestFactory ) {
171- Field field = ReflectionUtils .findField (
172- AbstractClientHttpRequestFactoryWrapper .class , "requestFactory" );
173- ReflectionUtils .makeAccessible (field );
174- return (ClientHttpRequestFactory ) ReflectionUtils .getField (field , requestFactory );
175- }
176-
177- private void addAuthentication (RestTemplate restTemplate , String username ,
178- String password ) {
179- if (username == null || password == null ) {
180- return ;
138+ if (username != null || password != null ) {
139+ builder = builder .basicAuthentication (username , password );
181140 }
182- ClientHttpRequestFactory requestFactory = getRequestFactory (restTemplate );
183- restTemplate .setRequestFactory (new BasicAuthenticationClientHttpRequestFactory (
184- new BasicAuthentication (username , password ), requestFactory ));
141+ this .restTemplate = builder .build ();
142+ this .restTemplate .setErrorHandler (new NoOpResponseErrorHandler ());
185143 }
186144
187145 /**
@@ -1038,25 +996,10 @@ public RestTemplate getRestTemplate() {
1038996 * @since 1.4.1
1039997 */
1040998 public TestRestTemplate withBasicAuth (String username , String password ) {
1041- RestTemplate restTemplate = new RestTemplateBuilder ()
1042- .requestFactory (getRequestFactorySupplier ())
1043- .messageConverters (getRestTemplate ().getMessageConverters ())
1044- .interceptors (getRestTemplate ().getInterceptors ())
1045- .uriTemplateHandler (getRestTemplate ().getUriTemplateHandler ()).build ();
1046- return new TestRestTemplate (restTemplate , username , password ,
999+ TestRestTemplate template = new TestRestTemplate (this .builder , username , password ,
10471000 this .httpClientOptions );
1048- }
1049-
1050- private Supplier <ClientHttpRequestFactory > getRequestFactorySupplier () {
1051- return () -> {
1052- try {
1053- return BeanUtils
1054- .instantiateClass (getRequestFactoryClass (getRestTemplate ()));
1055- }
1056- catch (BeanInstantiationException ex ) {
1057- return new ClientHttpRequestFactorySupplier ().get ();
1058- }
1059- };
1001+ template .setUriTemplateHandler (getRestTemplate ().getUriTemplateHandler ());
1002+ return template ;
10601003 }
10611004
10621005 @ SuppressWarnings ({ "rawtypes" , "unchecked" })
@@ -1078,7 +1021,7 @@ private URI applyRootUriIfNecessary(URI uri) {
10781021 }
10791022
10801023 /**
1081- * Options used to customize the Apache Http Client if it is used .
1024+ * Options used to customize the Apache HTTP Client.
10821025 */
10831026 public enum HttpClientOption {
10841027
0 commit comments