我正在与一个古老的服务进行集成,该服务将 jsessionid
添加到URL并重定向到它。 我使用 RestTemplate
与该服务通信。
问题在于,它会一直跟随重定向,因为我没有设置 jsession
cookie。
如何在Spring RestTemplate中关闭跟随重定向?
我正在与一个古老的服务进行集成,该服务将 jsessionid
添加到URL并重定向到它。 我使用 RestTemplate
与该服务通信。
问题在于,它会一直跟随重定向,因为我没有设置 jsession
cookie。
如何在Spring RestTemplate中关闭跟随重定向?
我想出了一种方法,不知道这是否是首选方法。
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
final HttpComponentsClientHttpRequestFactory factory =
new HttpComponentsClientHttpRequestFactory();
CloseableHttpClient build =
HttpClientBuilder.create().disableRedirectHandling().build();
factory.setHttpClient(build);
restTemplate.setRequestFactory(factory);
return restTemplate;
}
class CustomClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
super.prepareConnection(connection, httpMethod);
connection.setInstanceFollowRedirects(false);
}
}
@Configuration
public class AppConfig {
@Bean
public RestTemplate httpClient(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(10))
.setReadTimeout(Duration.ofSeconds(10))
.requestFactory(CustomClientHttpRequestFactory.class)
.build();
}
}
由于我发现上面的其他解决方案不适用于当前的Spring 5.x和Spring Boot 2.7,因此在此添加我的解决方案。
重要的是,Spring可以配置大约6种不同的HTTP客户端库。它们的配置方式不同,并且通过直接使用客户端库的API来完成。
以下是使用Apache HttpClient(历史上称为HttpComponents)创建测试RestTemplate
的示例。语法为Kotlin。
import org.apache.http.client.HttpClient
import org.apache.http.impl.client.HttpClients
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Profile
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory
import org.springframework.web.client.RestTemplate
@Bean @Qualifier("forTests")
fun restTemplateHttpsWithTestTrustStore(builder: RestTemplateBuilder): RestTemplate {
val httpClient: HttpClient = HttpClients.custom()
.disableRedirectHandling()
.build()
return builder.requestFactory { HttpComponentsClientHttpRequestFactory(httpClient) }.build()
}
然后进行测试:
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
)
class HttpsWorksTest {
@LocalServerPort private var port = 0
@Autowired @Qualifier("forTests") private lateinit var restTemplateTrustStore: RestTemplate
@Test
fun httpsSelfRequestTest() {
var url = "$proto://localhost:$port/someRediirectingEndpoint"
log.info("Requesting: GET $url")
var response = restTemplateTrustStore.getForEntity(url, String::class.java)
Assertions.assertThat(response.statusCode).isEqualTo(HttpStatus.SEE_OTHER)
}
}