ProxySelector:每个URL的不同代理

时间:2017-11-06 16:02:09

标签: java proxy uri http-proxy proxyselector

我正在尝试了解ProxySelector类的工作原理。我目前的代码如下:

    URI uri = new URI("http://google.com");
    proxySelector.select(uri);

我理解在调用proxySelector.select(uri);时,假设返回相应URI的代理列表。但我没有看到如何为每个URI设置代理。

我知道我可以使用setDefault()方法设置默认代理,但据我所知,这将设置系统范围的代理,而不是特定URI的代理。

我可能在这里遗漏了一些基本要点,但是如何为网址A设置一个代理(例如nonconjugate transpose)和为网址B设置不同的代理(例如http://google.com)然后拥有系统每次连接到相应的URL时自动选择正确的代理?

2 个答案:

答案 0 :(得分:2)

  1. 覆盖ProxySelector.select(URI uri)方法,您可以在其中实现自定义逻辑,以便为URI选择正确的代理或代理列表。

  2. 通过调用ProxySelector将新的自定义ProxySelector.setDefault(customProxySelector)设置为系统范围。

    URLConnection的任何子类都将使用ProxySelector,例如:

    URLConnection conn = url.openConnection();
    
  3. 或配置您将用于调用远程URI的框架,例如Spring RestTemplate:

    HttpRoutePlanner routePlanner = new SystemDefaultRoutePlanner(new MyProxySelector());
    
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory 
        = new HttpComponentsClientHttpRequestFactory(
            HttpClientBuilder.create()
                .setRoutePlanner(routePlanner)
                .build());
    restTemplate = new RestTemplate(clientHttpRequestFactory);
    
  4. 如果自定义逻辑没有为uri确定合适的代理,最好在自定义select(URI uri)中回退到默认的ProxySelector。

    请参阅我对ProxySelector example的其他答案。

    Java Networking and Proxies第4段ProxySelector )和ProxySelector Java docs中详细解释了网络和代理。

答案 1 :(得分:0)

实际上,仅通过使用增强的ProxySelector,它就可以很好地工作,而无需进行任何反思,该ProxySelector支持将特定网址列入白名单,并将其余的传递给委托(也称为默认)ProxySelector。

public class DelegatingProxySelector extends ProxySelector {

    private final Set<URI> allProxiedUri = new HashSet<>();

    private String proxyHost;
    private Integer proxyPort;

    private final ProxySelector delegate;

    public DelegatingProxySelector(
        String proxyHost, Integer proxyPort, ProxySelector delegate) {
        this.proxyHost = proxyHost;
        this.proxyPort = proxyPort;
        this.delegate = delegate;
    }

    @Override
    public List<Proxy> select(final URI uri) {
        if (allProxiedUri.contains(uri)) {
            final InetSocketAddress proxyAddress = InetSocketAddress
                .createUnresolved(proxyHost, proxyPort);
            return Collections.singletonList(new Proxy(Type.HTTP, proxyAddress));
        }
        return delegate.select(uri);
    }

    @Override
    public void connectFailed(final URI uri, final SocketAddress sa, final IOException ioe) {
        System.err.println("Unable to reach uri " + uri + " via proxy: " + ioe.getMessage());
    }
    
    public void addProxiedUri(URI uri) {
        allProxiedUri.add(uri);
    }
}

...

final DelegatingProxySelector delegatingProxySelector = new DelegatingProxySelector("localhost", 3128, ProxySelector.getDefault());
ProxySelector.setDefault(delegatingProxySelector);