2011-06-22 40 views
31

我有一個應用程序需要向Internet上的系統發出SOAP客戶端請求,因此它需要通過我們的HTTP代理。如何在不設置系統屬性的情況下爲JAX-WS請求使用HTTP代理?

// Cowboy-style. Blow away anything any other part of the application has set. 
System.getProperties().put("proxySet", "true"); 
System.getProperties().put("https.proxyHost", HTTPS_PROXY_HOST); 
System.getProperties().put("https.proxyPort", HTTPS_PROXY_PORT); 

或通過設置默認的ProxySelector(也是系統範圍的設置)::

// More Cowboy-style! Every thing Google has found says to do it this way!?!?! 
ProxySelector.setDefault(new MyProxySelector(HTTPS_PROXY_HOST, HTTPS_PROXY_PORT)); 

既不的

一個可以通過設置的全系統的值,如系統屬性要這樣做如果其他子系統想要通過不同的HTTP代理或沒有代理訪問Web服務器,這是一個明智的選擇。使用ProxySelector可以讓我配置哪些連接使用代理,但我必須在龐大的應用程序中爲每一件事情弄清楚。

一個合理的API將有一個方法需要一個java.net.Proxy對象,就像java.net.Socket(java.net.Proxy proxy)構造函數一樣。這樣,必要的設置對於需要設置它們的系統部分是本地的。有沒有辦法用JAX-WS來做到這一點?

我不想設置系統範圍的代理配置。

回答

5

如果您使用的是JAX-WS,您可能可以設置底層HttpURLConnection使用的套接字工廠。我發現模糊的跡象表明這可能是SSL(請參閱HTTPS SSLSocketFactory),但我不確定您是否可以爲常規HTTP連接執行此操作(或者坦率地說,它甚至可以工作:它們引用的JAXWSProperties類似乎是非標準的JDK類)。

如果你可以設置套接字工廠,那麼你可以配置一個自定義的套接字工廠,使用你想要的特定代理。

+1

的'JAXWSProperties'不會出現在我的JDK 1.6中存在。 – jbindel

+0

如果沒有別的東西出現,我會稍後再接受。 – jbindel

+0

您的方法確實有效,我們確實成功實現了它,但我決定使用'HttpsURLConnection.setDefaultSSLSocketFactory()'來支持API和JVM範圍的'SSLSocketFactory'設置。我們將把任何密鑰和證書組合成默認密鑰庫和信任庫的單個版本。 – jbindel

7

我推薦使用自定義ProxySelector。我有同樣的問題,它的工作很好,超級靈活。它也很簡單。

這裏是我的CustomProxySelector:

import org.hibernate.validator.util.LoggerFactory; 
import org.springframework.beans.factory.annotation.Value; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.*; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.logging.Logger; 

/** 
* So the way a ProxySelector works is that for all Connections made, 
* it delegates to a proxySelector(There is a default we're going to 
* override with this class) to know if it needs to use a proxy 
* for the connection. 
* <p>This class was specifically created with the intent to proxy connections 
* going to the allegiance soap service.</p> 
* 
* @author Nate 
*/ 
class CustomProxySelector extends ProxySelector { 

private final ProxySelector def; 

private Proxy proxy; 

private static final Logger logger = Logger.getLogger(CustomProxySelector.class.getName()); 

private List<Proxy> proxyList = new ArrayList<Proxy>(); 

/* 
* We want to hang onto the default and delegate 
* everything to it unless it's one of the url's 
* we need proxied. 
*/ 
CustomProxySelector(String proxyHost, String proxyPort) { 
    this.def = ProxySelector.getDefault(); 
    proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, (null == proxyPort) ? 80 : Integer.valueOf(proxyPort))); 
    proxyList.add(proxy); 
    ProxySelector.setDefault(this); 
} 

@Override 
public List<Proxy> select(URI uri) { 
    logger.info("Trying to reach URL : " + uri); 
    if (uri == null) { 
     throw new IllegalArgumentException("URI can't be null."); 
    } 
    if (uri.getHost().contains("allegiancetech")) { 
     logger.info("We're trying to reach allegiance so we're going to use the extProxy."); 
     return proxyList; 
    } 
    return def.select(uri); 
} 

/* 
* Method called by the handlers when it failed to connect 
* to one of the proxies returned by select(). 
*/ 
@Override 
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { 
    logger.severe("Failed to connect to a proxy when connecting to " + uri.getHost()); 
    if (uri == null || sa == null || ioe == null) { 
     throw new IllegalArgumentException("Arguments can't be null."); 
    } 
    def.connectFailed(uri, sa, ioe); 
} 

}

+2

我認爲這與我使用MyProxySelector的方法類似。 – jbindel

相關問題