Skip to content

Commit f450b28

Browse files
quaffphilwebb
authored andcommitted
Add redirects(...) method to RestTemplateBuilder
Add `redirects(...)` method to `RestTemplateBuilder` to allow redirect customization. This new method is required in 3.4 since the default redirect strategy for some clients has changed and users need a way to restore the old behavior. See gh-43258
1 parent 916efb6 commit f450b28

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

spring-boot-project/spring-boot-test/src/main/java/org/springframework/boot/test/web/client/TestRestTemplate.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.apache.hc.core5.ssl.TrustStrategy;
4848

4949
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
50+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
5051
import org.springframework.boot.web.client.RestTemplateBuilder;
5152
import org.springframework.boot.web.client.RootUriTemplateHandler;
5253
import org.springframework.core.ParameterizedTypeReference;
@@ -92,6 +93,7 @@
9293
* @author Andy Wilkinson
9394
* @author Kristine Jetzke
9495
* @author Dmytro Nosan
96+
* @author Yanming Zhou
9597
* @since 1.4.0
9698
*/
9799
public class TestRestTemplate {
@@ -946,6 +948,22 @@ public TestRestTemplate withBasicAuth(String username, String password) {
946948
return template;
947949
}
948950

951+
/**
952+
* Creates a new {@code TestRestTemplate} with the same configuration as this one,
953+
* except that it will use the given {@code redirects} strategies. The request factory
954+
* used is a new instance of the underlying {@link RestTemplate}'s request factory
955+
* type (when possible).
956+
* @param redirects the redirects
957+
* @return the new template
958+
* @since 3.4.1
959+
*/
960+
public TestRestTemplate withRedirects(Redirects redirects) {
961+
TestRestTemplate template = new TestRestTemplate(this.builder.redirects(redirects), null, null,
962+
this.httpClientOptions);
963+
template.setUriTemplateHandler(getRestTemplate().getUriTemplateHandler());
964+
return template;
965+
}
966+
949967
@SuppressWarnings({ "rawtypes", "unchecked" })
950968
private RequestEntity<?> createRequestEntityWithRootAppliedUri(RequestEntity<?> requestEntity) {
951969
return new RequestEntity(requestEntity.getBody(), requestEntity.getHeaders(), requestEntity.getMethod(),
@@ -988,7 +1006,10 @@ public enum HttpClientOption {
9881006

9891007
/**
9901008
* Enable redirects.
1009+
* @deprecated since 3.4.1 for removal in 3.6.0 in favor of
1010+
* {@link #withRedirects(Redirects)}
9911011
*/
1012+
@Deprecated(since = "3.4.1", forRemoval = true)
9921013
ENABLE_REDIRECTS,
9931014

9941015
/**
@@ -1032,7 +1053,8 @@ public CustomHttpComponentsClientHttpRequestFactory(HttpClientOption[] httpClien
10321053
Set<HttpClientOption> options = new HashSet<>(Arrays.asList(httpClientOptions));
10331054
this.cookieSpec = (options.contains(HttpClientOption.ENABLE_COOKIES) ? StandardCookieSpec.STRICT
10341055
: StandardCookieSpec.IGNORE);
1035-
this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS);
1056+
this.enableRedirects = options.contains(HttpClientOption.ENABLE_REDIRECTS)
1057+
|| settings.redirects() != Redirects.DONT_FOLLOW;
10361058
boolean ssl = options.contains(HttpClientOption.SSL);
10371059
if (settings.readTimeout() != null || ssl) {
10381060
setHttpClient(createHttpClient(settings.readTimeout(), ssl));

spring-boot-project/spring-boot-test/src/test/java/org/springframework/boot/test/web/client/TestRestTemplateTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.apache.hc.client5.http.config.RequestConfig;
2727
import org.junit.jupiter.api.Test;
2828

29+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
2930
import org.springframework.boot.test.web.client.TestRestTemplate.CustomHttpComponentsClientHttpRequestFactory;
3031
import org.springframework.boot.test.web.client.TestRestTemplate.HttpClientOption;
3132
import org.springframework.boot.web.client.RestTemplateBuilder;
@@ -66,6 +67,7 @@
6667
* @author Stephane Nicoll
6768
* @author Andy Wilkinson
6869
* @author Kristine Jetzke
70+
* @author Yanming Zhou
6971
*/
7072
class TestRestTemplateTests {
7173

@@ -129,6 +131,7 @@ void authenticated() {
129131
assertBasicAuthorizationCredentials(restTemplate, "user", "password");
130132
}
131133

134+
@SuppressWarnings("deprecation")
132135
@Test
133136
void options() {
134137
TestRestTemplate template = new TestRestTemplate(HttpClientOption.ENABLE_REDIRECTS);
@@ -139,6 +142,21 @@ void options() {
139142
assertThat(config.isRedirectsEnabled()).isTrue();
140143
}
141144

145+
@Test
146+
void redirects() {
147+
TestRestTemplate template = new TestRestTemplate().withRedirects(Redirects.DONT_FOLLOW);
148+
CustomHttpComponentsClientHttpRequestFactory factory = (CustomHttpComponentsClientHttpRequestFactory) template
149+
.getRestTemplate()
150+
.getRequestFactory();
151+
RequestConfig config = factory.createRequestConfig();
152+
assertThat(config.isRedirectsEnabled()).isFalse();
153+
154+
template = new TestRestTemplate().withRedirects(Redirects.FOLLOW);
155+
factory = (CustomHttpComponentsClientHttpRequestFactory) template.getRestTemplate().getRequestFactory();
156+
config = factory.createRequestConfig();
157+
assertThat(config.isRedirectsEnabled()).isTrue();
158+
}
159+
142160
@Test
143161
void restOperationsAreAvailable() {
144162
RestTemplate delegate = mock(RestTemplate.class);

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/client/RestTemplateBuilder.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.beans.BeanUtils;
3434
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
3535
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
36+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
3637
import org.springframework.boot.ssl.SslBundle;
3738
import org.springframework.http.client.ClientHttpRequest;
3839
import org.springframework.http.client.ClientHttpRequestFactory;
@@ -64,6 +65,7 @@
6465
* @author Kevin Strijbos
6566
* @author Ilya Lukyanovich
6667
* @author Scott Frederick
68+
* @author Yanming Zhou
6769
* @since 1.4.0
6870
*/
6971
public class RestTemplateBuilder {
@@ -501,6 +503,19 @@ public RestTemplateBuilder readTimeout(Duration readTimeout) {
501503
this.defaultHeaders, this.customizers, this.requestCustomizers);
502504
}
503505

506+
/**
507+
* Sets the redirect strategy on the underlying {@link ClientHttpRequestFactory}.
508+
* @param redirects the redirect strategy
509+
* @return a new builder instance.
510+
* @since 3.4.1
511+
*/
512+
public RestTemplateBuilder redirects(Redirects redirects) {
513+
return new RestTemplateBuilder(this.requestFactorySettings.withRedirects(redirects), this.detectRequestFactory,
514+
this.rootUri, this.messageConverters, this.interceptors, this.requestFactoryBuilder,
515+
this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders,
516+
this.customizers, this.requestCustomizers);
517+
}
518+
504519
/**
505520
* Sets the SSL bundle on the underlying {@link ClientHttpRequestFactory}.
506521
* @param sslBundle the SSL bundle

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/client/RestTemplateBuilderTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.mockito.junit.jupiter.MockitoExtension;
3333

3434
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
35+
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings.Redirects;
3536
import org.springframework.http.HttpHeaders;
3637
import org.springframework.http.HttpMethod;
3738
import org.springframework.http.MediaType;
@@ -73,6 +74,7 @@
7374
* @author Kevin Strijbos
7475
* @author Ilya Lukyanovich
7576
* @author Brian Clozel
77+
* @author Yanming Zhou
7678
*/
7779
@ExtendWith(MockitoExtension.class)
7880
class RestTemplateBuilderTests {
@@ -486,6 +488,13 @@ void unwrappingDoesNotAffectRequestFactoryThatIsSetOnTheBuiltTemplate() {
486488
assertThat(template.getRequestFactory()).isInstanceOf(BufferingClientHttpRequestFactory.class);
487489
}
488490

491+
@Test
492+
void configureRedirects() {
493+
assertThat(this.builder.redirects(Redirects.DONT_FOLLOW)).extracting("requestFactorySettings")
494+
.extracting("redirects")
495+
.isSameAs(Redirects.DONT_FOLLOW);
496+
}
497+
489498
private ClientHttpRequest createRequest(RestTemplate template) {
490499
return ReflectionTestUtils.invokeMethod(template, "createRequest", URI.create("http://localhost"),
491500
HttpMethod.GET);

0 commit comments

Comments
 (0)