Подтвердить что ты не робот

Как я могу использовать прокси-сервер HTTP для запроса JAX-WS без установки общесистемного свойства?

У меня есть приложение, которое должно сделать запрос клиента SOAP к системе в Интернете, поэтому ему нужно пройти через наш 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-прокси или без какого-либо прокси. Использование ProxySelector позволило бы мне настроить, какие соединения используют прокси-сервер, но я должен был бы понять это для каждой вещи в огромном приложении.

Разумный API будет иметь метод, который принял объект java.net.Proxy, как это делает конструктор java.net.Socket(java.net.Proxy proxy). Таким образом, необходимые настройки локальны для той части системы, которая должна быть установлена. Есть ли способ сделать это с помощью JAX-WS?

Я не хочу устанавливать общесистемную конфигурацию прокси.

4b9b3361

Ответ 1

Если вы используете JAX-WS, вы можете установить сокет factory, используемый базовым HttpURLConnection. Я вижу неопределенные признаки того, что это возможно для SSL (см. HTTPS SSLSocketFactory), но я не уверен, что вы можете сделать это для обычных HTTP-соединений (или, откровенно говоря, как это работает: класс JAXWSProperties, с которым они ссылаются, является нестандартным классом JDK).

Если вы можете установить сокет factory, тогда вы можете настроить собственный сокет factory, который использует определенный прокси-сервер, который вы хотите.

Ответ 2

Я рекомендую использовать пользовательский 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 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);
}

}