使用httpsproxy来选择jaxws请求,而不是在系统中设置它

时间:2015-08-05 19:23:01

标签: java web-services jax-ws http-proxy

我正在使用JAXWS客户端。我需要对某些选定的请求使用httpproxy,因此我不想将其设置为环境(将应用于所有请求)。我无法找到有关如何为每个请求设置httproxy的详细信息。

我能找到的最好的就是这篇文章:

How can I use an HTTP proxy for a JAX-WS request without setting a system-wide property?

但它并不是很详细,也没有提供任何线索。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:0)

据我所知,规范中没有一种方法 - 这意味着您可能必须在JAX-WS运行时提供程序中使用专有机制。

例如,如果您的JAX-WS客户端应用程序在IBM的WebSphere Application Server中运行,则可以在https.proxyHost上设置https.proxyPortRequestContext属性BindingProvider(您的客户):

//Set the https.proxyHost as a property on the RequestContext.
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put("https.proxyHost", "proxyHost1.ibm.com");
bp.getRequestContext().put("https.proxyPort", "80");

如果你正在使用Metro,那么JAX-WS参考实现the documentation表示它利用JDK的HttpsURLConnection来发出客户端HTTPS请求,但是通过在RequestContext BindingProvider上设置自定义属性,提供此提示以提供您自己的SSLSocketFactory

SSLSocketFactory sslSocketFactory = ...; //your implementation that uses a proxy
Map<String, Object> ctxt = ((BindingProvider)proxy).getRequestContext();
ctxt.put(JAXWSProperties.SSL_SOCKET_FACTORY, sslSocketFactory);

如果您不想使用密钥的JAXWSProperties常量,可以使用其字符串值:

ctxt.put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory",
         sslSocketFactory);

答案 1 :(得分:0)

我找出了从未调用过的自定义SSLSocketFactory(jaxws-rt-2.2.10-b140803.1500)。反射是唯一为每个服务设置代理并且不使用系统范围属性的解决方案。

void initClient(BindingProvider bindings, String endpoint) {
  Map<String, Object> context = bindings.getRequestContext();
  context.put(BindingProviderProperties.CONNECT_TIMEOUT, CONNECT_TIMEOUT);
  context.put(BindingProviderProperties.REQUEST_TIMEOUT, REQUEST_TIMEOUT);

  Map<String, List<String>> userHeaders = new LinkedHashMap<String, List<String>>();
  context.put("javax.xml.ws.http.request.headers", userHeaders);

  userHeaders.put("User-Agent", Collections.singletonList("{YOUR-USER-AGENT}"));
  userHeaders.put("Proxy-Athorization",
                  Collections.singletonList("Basic " + "{PROXY-AUTH}"));

  if (bindings instanceof WSBindingProvider) {
    WSBindingProvider wsbinding = (WSBindingProvider) bindings;
    WSPortInfo wsport = wsbinding.getPortInfo();
    EndpointAddress addr = wsport.getEndpointAddress();

    try {
      Field proxy = EndpointAddress.class.getDeclaredField("proxy");
      proxy.setAccessible(true);
      proxy.set(addr, PROXY);

      Field url = EndpointAddress.class.getDeclaredField("url");
      url.setAccessible(true);
      url.set(addr, new URL(new URI(endpoint).toASCIIString()));

    } catch (Exception e) {
      log.warning("Edit EndpointAddress error: " + e);
    }
  }
}

玩得开心!