2011-06-22 9 views
31

Mam aplikację, która musi wysłać żądanie klienta SOAP do systemu w Internecie, więc musi przejść przez nasz serwer proxy HTTP.Jak korzystać z serwera proxy HTTP dla żądania JAX-WS bez ustawiania właściwości systemowej?

Można to zrobić poprzez ustawienie wartości systemowych, takich jak właściwości systemowe:

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

lub ustawienie domyślne ProxySelector (również ustawienie całego systemu):

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

Żaden jest to mądry wybór, jeśli istnieje możliwość, że inne podsystemy będą chciały uzyskać dostęp do serwerów internetowych za pośrednictwem różnych serwerów proxy HTTP lub bez żadnego serwera proxy. Korzystanie z ProxySelector pozwoliłoby mi skonfigurować, które połączenia używają proxy, ale musiałbym to sobie wyobrazić dla każdej pojedynczej rzeczy w ogromnej aplikacji.

Rozsądny interfejs API miałby metodę, która pobierała obiekt java.net.Proxy, podobnie jak konstruktor java.net.Socket(java.net.Proxy proxy). W ten sposób niezbędne ustawienia są lokalne dla części systemu, która musi je ustawić. Czy jest jakiś sposób, aby to zrobić z JAX-WS?

Nie chcę ustawić ogólnosystemowej konfiguracji proxy.

Odpowiedz

5

Jeśli korzystasz z JAX-WS, możesz mieć możliwość ustawienia fabryki gniazd używanej przez ukrytą łączność HttpURLC. Widzę niejasne oznaki, że jest to możliwe dla SSL (zobacz HTTPS SSLSocketFactory), ale nie jestem pewien, czy możesz to zrobić dla zwykłych połączeń HTTP (lub całkiem szczerze mówiąc, jak to działa, nawet: klasa JAXWSProperties, do której się odnoszą, wydaje się być niestandardową Klasa JDK).

Jeśli możesz ustawić fabrykę gniazd, możesz skonfigurować niestandardową fabrykę gniazd, która używa określonego serwera proxy.

+1

Opcja 'JAXWSProperties' nie wydaje się istnieć w moim JDK 1.6. – jbindel

+0

Zaakceptuję to później, jeśli nic innego się nie pojawi. – jbindel

+0

Twoja metoda działa, i udało nam się ją z powodzeniem wdrożyć, ale zdecydowałem się przejść z obsługiwanymi interfejsami API i szerokim zakresem JVM ustawienia 'SSLSocketFactory' przy użyciu' HttpsURLConnection.setDefaultSSLSocketFactory() '. Połączymy wszystkie klucze i certyfikaty w jedną wersję domyślnego magazynu kluczy i magazynu zaufanych certyfikatów. – jbindel

7

Polecam używanie niestandardowego ProxySelector. Miałem ten sam problem i działa świetnie i jest bardzo elastyczny. To też jest proste.

Oto mój 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

Myślę, że to jest podobne do podejścia, które miałem z 'MyProxySelector'. – jbindel