Java 设置 JVM/JRE 以自动使用 Windows 代理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/376101/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting JVM/JRE to use Windows Proxy Automatically
提问by t3rse
I did see the question about setting the proxy for the JVM but what I want to ask is how one can utilize the proxy that is already configured (on Windows).
我确实看到了关于为 JVM 设置代理的问题,但我想问的是如何利用已经配置的代理(在 Windows 上)。
Here is a demonstration of my issue:
这是我的问题的演示:
- Go to your Control Panel->Java and set a proxy address.
- Run the following simple applet code (I'm using the Eclipse IDE):
- 转到您的控制面板-> Java 并设置代理地址。
- 运行以下简单的小程序代码(我使用的是 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);
}
}
The Applet displays "NONE" without regard to the settings you've placed in the Java Control Panel. What would be best would be if the Windows proxy settings (usually set in Internet Explorer) were what I could determine but doing an extra configuration step in the Java Control Panel would still be an acceptable solution.
Applet 显示“NONE”而不考虑您在 Java 控制面板中的设置。如果 Windows 代理设置(通常在 Internet Explorer 中设置)是我可以确定的,但在 Java 控制面板中执行额外的配置步骤仍然是可接受的解决方案,那将是最好的。
Thanks!
谢谢!
采纳答案by t3rse
It is possible to detect the proxy using the ProxySelectorclass and assign the system proxy by assigning environment variables with the setProperty method of the System class:
可以使用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()));
}
}
}
回答by Alain O'Dea
UPDATE:you need to have the System Property java.net.useSystemProxiesset to truefor my solution below to work.
更新:您需要将系统属性java.net.useSystemProxies设置为true才能使下面的解决方案起作用。
If you use java.net.URL.openStream()
to get an InputStream
for the web resource content you automatically get the same proxy used as Internet Explorer would use for that URL.
如果您用于java.net.URL.openStream()
获取InputStream
Web 资源内容的 ,您会自动获取 Internet Explorer 用于该 URL 的相同代理。
No need to go to the Java Control Panel or to display the proxy used.
无需转到 Java 控制面板或显示使用的代理。
回答by Hrvoje
java.net.URL.openStream()
is a shorthand for java.net.URL.openConnection().getInputStream()
.
java.net.URL.openStream()
是 的简写java.net.URL.openConnection().getInputStream()
。
回答by Flo
I found an odd behavior experimenting with the suggested code here.
我在此处尝试使用建议的代码时发现了一种奇怪的行为。
It appears that, after a default ProxySelector has been set, regular socket code (e.g. creating a new Socket) does not work anymore, because it tries to use a socks server (not sure why it would do this, but for me it does).
看起来,在设置了默认的 ProxySelector 之后,常规套接字代码(例如,创建一个新的套接字)不再起作用,因为它尝试使用袜子服务器(不知道为什么会这样做,但对我来说确实如此) .
So if you, when calling
所以如果你在打电话时
Socket socket = new Socket(host, port);
you receive such a SocketException:
您收到这样的 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)
then try setting the default ProxySelector back to null:
然后尝试将默认的 ProxySelector 设置回 null:
ProxySelector.setDefault(null);
For me this resulted in the following small Java class which I now use to simply retrieve the systems proxy settings without having it affect the further usage of Sockets() of the application, yet configuring the system properly to use the proxy:
对我来说,这导致了以下小 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;
}
}
回答by Juan Martin Lichowski
This might be a little late, but I ran into the same problem. The way I fixed it is by adding the following system property:
这可能有点晚了,但我遇到了同样的问题。我修复它的方法是添加以下系统属性:
-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:
现在请注意,此属性仅在启动时设置一次,因此在您运行应用程序时无法更改。从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.
java.net.useSystemProxies (default: false) ... 请注意,此属性仅在启动时检查一次。
回答by Mahdi
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");
}