I had to connect through a proxy to call an external API using RestTemplete, so I looked it up.
Postscript Added a workaround for the problem that the body cannot be sent by the GET method.
version SpringBoot 2.1.6.RELEASE HttpClient 4.5.9
Implement the setting process in the customize method.
Set the proxy host (host, port number) in HttpClientBuilder. If authentication (username, password) is required, set the authentication information in CredentialProvider and set it in HttpClientBuilder.
Set the timeout setting in HttpComponentsClientHttpRequestFactory.
RestTemplateConfig.java
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestTemplateConfig implements RestTemplateCustomizer {
@Value("${proxy.host:#{null}}")
private String proxyHost;
@Value("${proxy.port:0}")
private int proxyPort;
@Value("${proxy.user:#{null}}")
private String proxyUser;
@Value("${proxy.password:#{null}}")
private String proxyPassword;
@Value("${api.connect.timeout:0}")
private int connectTimeout;
@Value("${api.read.timeout:0}")
private int readTimeout;
@Override
public void customize(RestTemplate restTemplate) {
HttpClientBuilder builder;
if (proxyHost != null && !proxyHost.isEmpty() && proxyPort != 0) {
builder = HttpClientBuilder.create().setProxy(new HttpHost(proxyHost, proxyPort));
if (proxyUser != null && !proxyUser.isEmpty() && proxyPassword != null && !proxyPassword.isEmpty()) {
AuthScope authScope = new AuthScope(proxyHost, proxyPort);
UsernamePasswordCredentials usernamePassword = new UsernamePasswordCredentials(proxyUser, proxyPassword);
BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(authScope, usernamePassword);
builder.setDefaultCredentialsProvider(credentialsProvider);
}
}
else {
builder = HttpClientBuilder.create();
}
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(builder.build());
if (connectTimeout > 0) {
requestFactory.setConnectTimeout(connectTimeout);
}
if (readTimeout > 0) {
requestFactory.setReadTimeout(readTimeout);
}
restTemplate.setRequestFactory(requestFactory);
};
}
If you keep the default, you cannot send the request body with the GET method. HttpComponentsClientHttpRequestFactory can now be extended to send request bodies with the GET method.
reference Making a GET request with request body using Spring RestTemplate
class HttpEntityEnclosingRequest extends HttpEntityEnclosingRequestBase {
HttpEntityEnclosingRequest(URI uri) {
setURI(uri);
}
@Override
public String getMethod() {
return HttpMethod.GET.name();
}
}
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(builder.build()) {
@Override
protected HttpUriRequest createHttpUriRequest(HttpMethod httpMethod, URI uri) {
if (httpMethod == HttpMethod.GET) {
return new HttpEntityEnclosingRequest(uri);
}
return super.createHttpUriRequest(httpMethod, uri);
}
};
Recommended Posts