首页 > 解决方案 > ResourceAccessException with SocketException:连接重置,通过代理进行 REST 调用时

问题描述

语境

我有一个后端服务,可以对不同的系统进行 REST 调用 ( <target-url> )。另一个系统只能通过代理访问,并且需要安全令牌(cookie)。

执行

我使用 RestTemplateCustomizer 设置代理,如下所示:

static class ProxyCustomizer implements RestTemplateCustomizer {

    private final HttpHost proxy;

    ProxyCustomizer(final HttpHost proxy) {
      this.proxy = proxy;
    }

    @Override
    public void customize(final RestTemplate restTemplate) {
      final HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(new DefaultProxyRoutePlanner(this.proxy) {

        @Override
        public HttpHost determineProxy(final HttpHost target, final HttpRequest request, final HttpContext context)
            throws HttpException {
          return super.determineProxy(target, request, context);
        }

      }).build();
      restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
    }
  }

REST 模板的调用方式如下:

    final HttpHost proxy = new HttpHost("<proxy-url>");
    this.restTemplate = new RestTemplateBuilder(new ProxyCustomizer(proxy)).build();

我正在使用这些标题:

    final HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Collections.singletonList(ACCEPT));
    headers.set(HttpHeaders.COOKIE, securityToken);
    return headers;

例外

我可以访问的所有日志如下:

Failed to get Information from Service.org.springframework.web.client.ResourceAccessException: 
    I/O error on GET request for "<target-url>": Connection reset; 
    nested exception is java.net.SocketException: Connection reset

没有代理我得到以下异常:

Failed to get Information from Service.org.springframework.web.client.ResourceAccessException: 
    I/O error on GET request for "<target-url>": <target-host>: Name or service not known; 
    nested exception is java.net.UnknownHostException: <target-host>: Name or service not known

我将不胜感激您能提供的任何帮助。

标签: javaspringproxyresttemplate

解决方案


我让它工作。

我的解决方案不是使用 RestRemplateCustomizer,而是在创建 http 客户端时设置代理。

    try {
      clientBuilder.setSSLContext(SSLContext.getDefault());
    } catch (final NoSuchAlgorithmException ex) {
      log.error("Error while setting SSL Context");
      throw new IllegalStateException(ex);
    }

    if (null != configuration && null != configuration.getProxyHost()) {
      final HttpHost proxy = new HttpHost(configuration.getProxyHost(), configuration.getProxyPort());
      clientBuilder.setRoutePlanner(new PcssProxyRoutePlanner(proxy));
      clientBuilder.setSSLHostnameVerifier((hostname, session) -> true);
    } else {
      clientBuilder.setRoutePlanner(new SystemDefaultRoutePlanner(new DefaultProxySelector()));
    }

推荐阅读