java - ¿Cómo puedo usar un proxy HTTP para una solicitud JAX-WS sin establecer una propiedad para todo el sistema?
soap (2)
Tengo una aplicación que necesita hacer una solicitud del cliente SOAP a un sistema en Internet, por lo que debe pasar por nuestro proxy HTTP.
Uno puede hacer esto estableciendo valores para todo el sistema, como las propiedades del sistema:
// 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);
O configurando el ProxySelector predeterminado (también una configuración de todo el sistema):
// More Cowboy-style! Every thing Google has found says to do it this way!?!?!
ProxySelector.setDefault(new MyProxySelector(HTTPS_PROXY_HOST, HTTPS_PROXY_PORT));
Ninguno de estos es una buena elección si existe la posibilidad de que otros subsistemas quieran acceder a los servidores web a través de diferentes proxies HTTP o sin ningún proxy. El uso de ProxySelector
me permitiría configurar qué conexiones usar el proxy, pero tendría que averiguarlo para cada cosa en la gran aplicación.
Una API razonable tendría un método que tomara un objeto java.net.Proxy
como lo hace el constructor java.net.Socket(java.net.Proxy proxy)
. De esta forma, las configuraciones necesarias son locales para la parte del sistema que necesita establecerlas. ¿Hay alguna forma de hacer esto con un JAX-WS?
No quiero establecer una configuración de proxy de todo el sistema.
Recomiendo usar un ProxySelector personalizado. Tuve el mismo problema y funciona muy bien y es súper flexible. Es simple también
Aquí está mi 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);
}
}
Si está utilizando JAX-WS, es posible que pueda configurar la fábrica de socket utilizada por HttpURLConnection subyacente. Veo signos vagos de que esto es posible para SSL (consulte HTTPS SSLSocketFactory ), pero no estoy seguro de si puede hacer eso para las conexiones HTTP normales (o, francamente, cómo eso funciona: la clase JAXWSProperties a la que hacen referencia parece no serlo). clase JDK estándar).
Si puede establecer la fábrica de sockets, puede configurar una fábrica de sockets personalizada que use el proxy específico que desee.