Proxy and timeout settings when calling API in Spring Rest Template

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

RestTemplateCustomizer interface for setting RestTemplate

Implement the setting process in the customize method.

Proxy settings

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.

Timeout settings

Set the timeout setting in HttpComponentsClientHttpRequestFactory.

Class-wide code

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);
    };
}

Allow the body to be sent with the GET method

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

Proxy and timeout settings when calling API in Spring Rest Template
Settings when calling API using CSRF measures of Spring Security in JMeter
Implement REST API in Spring Boot
Introduce swagger-ui to REST API implemented in Spring Boot
Implement REST API with Spring Boot and JPA (Application Layer)
Implement REST API with Spring Boot and JPA (Infrastructure layer)
How to call and use API in Java (Spring Boot)
Create API to send and receive Json data in Spring
Implement REST API with Spring Boot and JPA (domain layer)
Spring with Kotorin --4 REST API design
How to pass a proxy when throwing REST over SSL in Java