添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to do REST calls with Spring. As I understand, the right way to go is using RestTemplate (?). Problem is, I'm behind a proxy.

This is my code right now:

SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
InetSocketAddress address = new InetSocketAddress(host, 3128);
Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(factory);

It seems to work, but I need to authenticate at the proxy, but how is this done? The Proxy type as well as the SimpleClientHttpRequestFactory type don't seem to handle credentials. Without credentials, I'm getting just 407...

After quite a few different options I settled on The below code due to the ability to set the proxy for the RestTemplate at creation so I could refactor it into a separate method. Just to note it also has an additional dependency so keep that in mind.

private RestTemplate createRestTemplate() throws Exception {
    final String username = "myusername";
    final String password = "myPass";
    final String proxyUrl = "proxy.nyc.bigtower.com";
    final int port = 8080;
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials( 
        new AuthScope(proxyUrl, port), 
        new UsernamePasswordCredentials(username, password)
    HttpHost myProxy = new HttpHost(proxyUrl, port);
    HttpClientBuilder clientBuilder = HttpClientBuilder.create();
    clientBuilder.setProxy(myProxy).setDefaultCredentialsProvider(credsProvider).disableCookieManagement();
    HttpClient httpClient = clientBuilder.build();
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
    factory.setHttpClient(httpClient);
    return new RestTemplate(factory);

//Dependencies I used.

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.2</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>4.2.5.RELEASE</version>
</dependency>
                What if I'm using Spring 3.0.1? I don't have the class HttpComponentsClientHttpRequestFactory
– carlitos081
                Jan 10, 2017 at 23:33
                This solution is not backwards compatible to Spring 3 you will need to create the request factory differently.   I am not familiar with Spring 3 so yo will have to do some research.  I strongly recommend using Spring 4 as Spring 5 is already on the way.
– Matthew Fontana
                Jan 11, 2017 at 12:21
                I know but unfortunately, on my project, is not possible upgrade a newer version . I turned around using an unauthenticated proxy and using SimpleClientHttpRequestFactory (Spring 3.0.5) instead of HttpComponentsClientHttpRequestFactory(Since Spring 3.1)
– carlitos081
                Jan 11, 2017 at 12:47
RestTemplate restTemplate = new RestTemplate();
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials( new AuthScope("proxyHost", "proxyPort"), new UsernamePasswordCredentials("proxyUser", "proxyPass") );
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.useSystemProperties();
clientBuilder.setProxy(new HttpHost("proxyHost", "proxyPort"));
clientBuilder.setDefaultCredentialsProvider(credsProvider);
clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
CloseableHttpClient client = clientBuilder.build();
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setHttpClient(client);
restTemplate.setRequestFactory(factory);

If your proxy require basic auth, you can simply set the HTTP header Proxy-Authorization to handle authentication:

final SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
final InetSocketAddress address = new InetSocketAddress(host, 3128);
final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
factory.setProxy(proxy);
final String username = "Aladdin";
final String password = "open sesame";
final RestTemplate restTemplate = new RestTemplateBuilder()
    .requestFactory(() -> factory)
    .defaultHeader(HttpHeaders.PROXY_AUTHORIZATION, "Basic " + Base64.getEncoder().encodeToString((username + ':' + password).getBytes(StandardCharsets.UTF_8)))
    .build();

You don't need to use an additional dependency for that.