如何在Java中实现无代理连接?

7
我如何避免使用 ProxySelector 在使用 URLConnection 进行连接时,或者说如何确保获得不受 Java 知道的任何代理影响的连接?
我认为这就是 Proxy.NO_PROXY 的作用。引用 Javadoc 中的话:
“表示直接连接的代理设置,基本上告诉协议处理程序不要使用任何代理”
然而,这样的连接仍将通过 ProxySelector。我不明白为什么?
我进行了一个小测试来证明我的观点:
public static void main(String[] args) throws MalformedURLException, IOException {
    ProxySelector.setDefault(new MyProxySelector());
    URL url = new URL("http://foobar.com/x1/x2");
    URLConnection connection = url.openConnection(Proxy.NO_PROXY);
    connection.connect();
}

还有一个虚拟的ProxySelector,它什么也不做,只记录正在进行的操作:

public class MyProxySelector extends ProxySelector {

    @Override
    public List<Proxy> select(URI uri) {
        System.out.println("MyProxySelector called with URI = " + uri);
        return Collections.singletonList(Proxy.NO_PROXY);
    }

    @Override
    public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {}
}

这将打印:

"MyProxySelector called with URI = socket://foobar.com:80"

(注意协议已从http更改为socket)。
当然,我可以以这样的方式创建我的ProxySelector,以便在URI方案为socket时它总是返回Proxy.NO_PROXY,但我猜可能会有一些场合,在该网站上存在SOCKS代理,那么它就不成立了。
让我重新陈述问题:我需要一种方法来确保特定的URLConnection不使用代理,而不管系统属性或安装了什么ProxySelector。

1
我认为你也可以设置 ProxySelector.setDefault(null);。这将允许直接连接。 - Tunaki
@Tunaki。不幸的是,这将完全关闭ProxySelector并且对于所有连接都是如此。 - peterh
1
直接连接经过ProxySelector的事实是一项实现细节。你为什么关心呢?你有一个真正的问题吗? - user207421
@EJP。我添加了最后一句话。我认为,要求能够拥有无代理连接是公平和合理的要求。 - peterh
@Holger。你很接近了。当您在URL连接上请求NO_PROXY时,会创建一个类型为SocksSocketImpl的套接字。这只是一个普通的SOCKS连接,并将尝试查找配置的任何SOCKS代理...而不管您对NO_PROXY的请求。我认为这并没有让任何人感到困扰,也没有被报告为错误的主要原因是(1)很少有人会尝试自己的ProxySelector,更重要的是:(2)很少有站点安装SOCKS代理。 - peterh
显示剩余2条评论
1个回答

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接