web-dev-qa-db-fra.com

Comment puis-je utiliser un proxy HTTP pour une demande JAX-WS sans définir de propriété à l'échelle du système?

J'ai une application qui doit faire une demande client SOAP à un système sur Internet, donc elle doit passer par notre proxy HTTP.

On peut le faire en définissant des valeurs à l'échelle du système telles que les propriétés du système:

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

Ou en définissant le ProxySelector par défaut (également un paramètre à l'échelle du système):

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

Aucun de ces éléments n'est un choix judicieux s'il existe la possibilité que d'autres sous-systèmes souhaitent accéder aux serveurs Web via différents proxy HTTP ou sans proxy. L'utilisation de ProxySelector me permettrait de configurer les connexions qui utilisent le proxy, mais je devrais le comprendre pour chaque chose dans l'énorme application.

Une API raisonnable aurait une méthode qui prendrait un objet Java.net.Proxy Tout comme le constructeur Java.net.Socket(Java.net.Proxy proxy). De cette façon, les paramètres nécessaires sont locaux pour la partie du système qui doit les définir. Existe-t-il un moyen de le faire avec un JAX-WS?

Je ne souhaite pas définir de configuration de proxy à l'échelle du système.

33
jbindel

Si vous utilisez JAX-WS, vous pourrez peut-être définir la fabrique de socket utilisée par la connexion HttpURLConnection sous-jacente. Je vois des signes vagues que cela est possible pour SSL (voir HTTPS SSLSocketFactory ) mais je ne suis pas certain si vous pouvez le faire pour les connexions HTTP régulières (ou franchement comment cela fonctionne même: la classe JAXWSProperties qu'ils semble être une classe JDK non standard).

Si vous pouvez définir la fabrique de socket, vous pouvez configurer une fabrique de socket personnalisée qui utilise le proxy spécifique que vous souhaitez.

5
Femi

Je recommande d'utiliser un ProxySelector personnalisé. J'ai eu le même problème et cela fonctionne très bien et est super flexible. C'est simple aussi.

Voici mon 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);
}

}

10
Uncle Iroh