@ -19,12 +19,14 @@ package org.springframework.boot.web.client;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Field ;
import java.lang.reflect.Method ;
import java.nio.charset.Charset ;
import java.time.Duration ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.Collection ;
import java.util.Collections ;
import java.util.LinkedHashSet ;
import java.util.List ;
import java.util.Set ;
import java.util.function.Consumer ;
import java.util.function.Supplier ;
@ -33,7 +35,6 @@ import org.springframework.beans.BeanUtils;
import org.springframework.http.client.AbstractClientHttpRequestFactoryWrapper ;
import org.springframework.http.client.ClientHttpRequestFactory ;
import org.springframework.http.client.ClientHttpRequestInterceptor ;
import org.springframework.http.client.InterceptingClientHttpRequestFactory ;
import org.springframework.http.converter.HttpMessageConverter ;
import org.springframework.util.Assert ;
import org.springframework.util.CollectionUtils ;
@ -372,26 +373,32 @@ public class RestTemplateBuilder {
}
/ * *
* Add HTTP basic authentication to requests . See
* { @link BasicAuthenticationClientHttpRequestFactory } for details .
* Add HTTP Basic Authentication to requests with the given username / password pair ,
* unless a custom Authorization header has been set before .
* @param username the user name
* @param password the password
* @return a new builder instance
* @since 2.1 .0
* @see # basicAuthentication ( String , String , Charset )
* /
public RestTemplateBuilder basicAuthentication ( String username , String password ) {
return basicAuthentication ( new BasicAuthentication ( username , password ) ) ;
return basicAuthentication ( username , password , null ) ;
}
/ * *
* Add HTTP basic authentication to requests . See
* { @link BasicAuthenticationClientHttpRequestFactory } for details .
* @param basicAuthentication the authentication
* Add HTTP Basic Authentication to requests with the given username / password pair ,
* unless a custom Authorization header has been set before .
* @param username the user name
* @param password the password
* @param charset the charset to use
* @return a new builder instance
* @since 2.2 .0
* @see # basicAuthentication ( String , String )
* /
public RestTemplateBuilder basicAuthentication (
BasicAuthentication basicAuthentication ) {
public RestTemplateBuilder basicAuthentication ( String username , String password ,
Charset charset ) {
BasicAuthentication basicAuthentication = new BasicAuthentication ( username ,
password , charset ) ;
return new RestTemplateBuilder ( this . detectRequestFactory , this . rootUri ,
this . messageConverters , this . requestFactorySupplier ,
this . uriTemplateHandler , this . errorHandler , basicAuthentication ,
@ -518,7 +525,6 @@ public class RestTemplateBuilder {
* @see RestTemplateBuilder # build ( )
* @see # configure ( RestTemplate )
* /
public < T extends RestTemplate > T build ( Class < T > restTemplateClass ) {
return configure ( BeanUtils . instantiateClass ( restTemplateClass ) ) ;
}
@ -532,7 +538,13 @@ public class RestTemplateBuilder {
* @see RestTemplateBuilder # build ( Class )
* /
public < T extends RestTemplate > T configure ( T restTemplate ) {
configureRequestFactory ( restTemplate ) ;
ClientHttpRequestFactory requestFactory = buildRequestFactory ( ) ;
if ( requestFactory ! = null ) {
restTemplate . setRequestFactory ( requestFactory ) ;
}
if ( this . basicAuthentication ! = null ) {
configureBasicAuthentication ( restTemplate ) ;
}
if ( ! CollectionUtils . isEmpty ( this . messageConverters ) ) {
restTemplate . setMessageConverters ( new ArrayList < > ( this . messageConverters ) ) ;
}
@ -545,9 +557,6 @@ public class RestTemplateBuilder {
if ( this . rootUri ! = null ) {
RootUriTemplateHandler . addTo ( restTemplate , this . rootUri ) ;
}
if ( this . basicAuthentication ! = null ) {
configureBasicAuthentication ( restTemplate ) ;
}
restTemplate . getInterceptors ( ) . addAll ( this . interceptors ) ;
if ( ! CollectionUtils . isEmpty ( this . restTemplateCustomizers ) ) {
for ( RestTemplateCustomizer customizer : this . restTemplateCustomizers ) {
@ -557,7 +566,13 @@ public class RestTemplateBuilder {
return restTemplate ;
}
private void configureRequestFactory ( RestTemplate restTemplate ) {
/ * *
* Build a new { @link ClientHttpRequestFactory } instance using the settings of this
* builder .
* @return a { @link ClientHttpRequestFactory } or { @code null }
* @since 2.2 .0
* /
public ClientHttpRequestFactory buildRequestFactory ( ) {
ClientHttpRequestFactory requestFactory = null ;
if ( this . requestFactorySupplier ! = null ) {
requestFactory = this . requestFactorySupplier . get ( ) ;
@ -569,27 +584,24 @@ public class RestTemplateBuilder {
if ( this . requestFactoryCustomizer ! = null ) {
this . requestFactoryCustomizer . accept ( requestFactory ) ;
}
restTemplate . setRequestFactory ( requestFactory ) ;
}
return requestFactory ;
}
private void configureBasicAuthentication ( RestTemplate restTemplate ) {
ClientHttpRequestFactory requestFactory = restTemplate . getRequestFactory ( ) ;
while ( requestFactory instanceof InterceptingClientHttpRequestFactory
| | requestFactory instanceof BasicAuthenticationClientHttpRequestFactory ) {
requestFactory = unwrapRequestFactory (
( ( AbstractClientHttpRequestFactoryWrapper ) requestFactory ) ) ;
List< ClientHttpRequestInterceptor > interceptors = null ;
if ( ! restTemplate . getInterceptors ( ) . isEmpty ( ) ) {
// Stash and clear the interceptors so we can access the real factory
interceptors = new ArrayList < > ( restTemplate . getInterceptors ( ) ) ;
restTemplate . getInterceptors ( ) . clear ( ) ;
}
ClientHttpRequestFactory requestFactory = restTemplate . getRequestFactory ( ) ;
restTemplate . setRequestFactory ( new BasicAuthenticationClientHttpRequestFactory (
this . basicAuthentication , requestFactory ) ) ;
// Restore the original interceptors
if ( interceptors ! = null ) {
restTemplate . getInterceptors ( ) . addAll ( interceptors ) ;
}
private static ClientHttpRequestFactory unwrapRequestFactory (
AbstractClientHttpRequestFactoryWrapper requestFactory ) {
Field field = ReflectionUtils . findField (
AbstractClientHttpRequestFactoryWrapper . class , "requestFactory" ) ;
ReflectionUtils . makeAccessible ( field ) ;
return ( ClientHttpRequestFactory ) ReflectionUtils . getField ( field , requestFactory ) ;
}
private < T > Set < T > append ( Set < T > set , Collection < ? extends T > additions ) {
@ -638,10 +650,16 @@ public class RestTemplateBuilder {
private ClientHttpRequestFactory unwrapRequestFactoryIfNecessary (
ClientHttpRequestFactory requestFactory ) {
if ( ! ( requestFactory instanceof AbstractClientHttpRequestFactoryWrapper ) ) {
return requestFactory ;
}
Field field = ReflectionUtils . findField (
AbstractClientHttpRequestFactoryWrapper . class , "requestFactory" ) ;
ReflectionUtils . makeAccessible ( field ) ;
ClientHttpRequestFactory unwrappedRequestFactory = requestFactory ;
while ( unwrappedRequestFactory instanceof AbstractClientHttpRequestFactoryWrapper ) {
unwrappedRequestFactory = unwrapRequestFactory (
( ( AbstractClientHttpRequestFactoryWrapper ) unwrappedRequestFactory ) ) ;
unwrappedRequestFactory = ( ClientHttpRequestFactory ) ReflectionUtils
.getField ( field , unwrappedRequestFactory ) ;
}
return unwrappedRequestFactory ;
}