35

我确实看到了关于为 JVM 设置代理的问题,但我想问的是如何利用已经配置的代理(在 Windows 上)。

这是我的问题的演示:

  1. 转到您的控制面板-> Java 并设置代理地址。
  2. 运行以下简单的小程序代码(我使用的是 Eclipse IDE):
import java.awt.Graphics;
import javax.swing.JApplet;
import java.util.*;

public class Stacklet extends JApplet {
    private String message;
    public void init(){
        Properties props = System.getProperties();
        message = props.getProperty("http.proxyHost", "NONE");      
        message = (message.length() == 0)? "NONE": message;
    }

    public void paint(Graphics g)
    {
        g.drawString(message, 20, 20);
    }
}

与您在 Java 控制面板中放置的设置无关,Applet 会显示“NONE”。如果 Windows 代理设置(通常在 Internet Explorer 中设置)是我可以确定的,但在 Java 控制面板中执行额外的配置步骤仍然是可接受的解决方案,那么最好的办法是。

谢谢!

4

6 回答 6

39

可以使用ProxySelector类检测代理,并通过使用System 类的 setProperty 方法分配环境变量来分配系统代理:

System.setProperty("java.net.useSystemProxies", "true");
System.out.println("detecting proxies");
List l = null;
try {
    l = ProxySelector.getDefault().select(new URI("http://foo/bar"));
} 
catch (URISyntaxException e) {
    e.printStackTrace();
}
if (l != null) {
    for (Iterator iter = l.iterator(); iter.hasNext();) {
        java.net.Proxy proxy = (java.net.Proxy) iter.next();
        System.out.println("proxy type: " + proxy.type());

        InetSocketAddress addr = (InetSocketAddress) proxy.address();

        if (addr == null) {
            System.out.println("No Proxy");
        } else {
            System.out.println("proxy hostname: " + addr.getHostName());
            System.setProperty("http.proxyHost", addr.getHostName());
            System.out.println("proxy port: " + addr.getPort());
            System.setProperty("http.proxyPort", Integer.toString(addr.getPort()));
        }
    }
}
于 2008-12-19T17:58:09.927 回答
14

这可能有点晚了,但我遇到了同样的问题。我修复它的方法是添加以下系统属性:

-Djava.net.useSystemProxies=true

Now, note that this property is set only once at startup, so it can't change when you run your application. From https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies:

java.net.useSystemProxies (default: false) ... Note that this property is checked only once at startup.

于 2015-12-10T14:53:04.927 回答
11

我在此处尝试使用建议的代码时发现了一个奇怪的行为。

看来,在设置了默认 ProxySelector 后,常规套接字代码(例如创建新套接字)不再起作用,因为它尝试使用 socks 服务器(不知道为什么会这样做,但对我来说确实如此) .

所以如果你在打电话的时候

Socket socket = new Socket(host, port);

你收到这样的 SocketException:

java.net.SocketException: Malformed reply from SOCKS server
    at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)

然后尝试将默认 ProxySelector 设置回 null:

ProxySelector.setDefault(null);

对我来说,这导致了以下小型 Java 类,我现在使用它来简单地检索系统代理设置,而不会影响应用程序的 Sockets() 的进一步使用,同时正确配置系统以使用代理:

public class ProxyConfig {

  private static String host;
  private static int port;

  public static void init() {
    System.setProperty("java.net.useSystemProxies", "true");
    Proxy proxy = getProxy();
    if (proxy != null) {
      InetSocketAddress addr = (InetSocketAddress) proxy.address();
      host = addr.getHostName();
      port = addr.getPort();

      System.setProperty("java.net.useSystemProxies", "false");
      System.setProperty("http.proxyHost", host);
      System.setProperty("http.proxyPort", ""+port);

    }
    System.setProperty("java.net.useSystemProxies", "false");
  }

  public static String getHost() {
    return host;
  }

  public static int getPort() {
    return port;
  }

  private static Proxy getProxy() {
    List<Proxy> l = null;
    try {
      ProxySelector def = ProxySelector.getDefault();

      l = def.select(new URI("http://foo/bar"));
      ProxySelector.setDefault(null);
    } catch (Exception e) {
      e.printStackTrace();
    }
    if (l != null) {
      for (Iterator<Proxy> iter = l.iterator(); iter.hasNext();) {
        java.net.Proxy proxy = iter.next();
        return proxy;
      }
    }
    return null;
  }
}
于 2011-08-16T21:43:09.067 回答
3

java.net.URL.openStream()是 的简写java.net.URL.openConnection().getInputStream()

于 2010-12-07T13:37:48.783 回答
2

更新:您需要将系统属性java.net.useSystemProxies设置为true,我的下面的解决方案才能正常工作。

如果您用于java.net.URL.openStream()获取InputStreamWeb 资源内容,则会自动获取与 Internet Explorer 用于该 URL 的代理相同的代理。

无需转到 Java 控制面板或显示使用的代理。

于 2010-09-30T12:43:05.670 回答
2
try{
    System.setProperty("java.net.useSystemProxies", "true");
    String prx = ProxySelector.getDefault().select(new URI("http://www.google.com")).get(0).address().toString();
    JOptionPane.showMessageDialog(null, prx);
} catch(Exception e){
    JOptionPane.showMessageDialog(null, "no proxy");
}
于 2018-11-01T21:39:21.213 回答