很多时候,Java应用程序需要连接到Internet。最常见的例子发生在读取XML文件并需要下载其模式时。
我在代理服务器后面。如何将JVM设置为使用代理?
很多时候,Java应用程序需要连接到Internet。最常见的例子发生在读取XML文件并需要下载其模式时。
我在代理服务器后面。如何将JVM设置为使用代理?
当前回答
正如在其他回答中指出的那样,如果您需要使用经过身份验证的代理,纯粹使用命令行变量是没有可靠的方法来做到这一点的——如果您正在使用别人的应用程序,并且不想弄乱源代码,这是很烦人的。
Will Iverson在使用HttpProxy连接到具有抢先身份验证的主机上提出了有用的建议,使用代理管理工具如proxfier (http://www.proxifier.com/ for Mac OS X和Windows)来处理这个问题。
例如,使用proxfier,您可以将其设置为仅拦截要通过其(经过身份验证的)代理进行管理和重定向的java命令。在这种情况下,你需要将proxyHost和proxyPort的值设置为空,例如传入-Dhttp。proxyHost = -Dhttp。proxyPort=到您的java命令。
其他回答
从Java文档(不是javadoc API):
http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
设置JVM标志http。proxyHost和http。在命令行上启动JVM时使用proxyPort。 这通常是在shell脚本(Unix)或bat文件(Windows)中完成的。下面是Unix shell脚本的示例:
JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800
java ${JAVA_FLAGS} ...
当使用JBoss或WebLogic等容器时,我的解决方案是编辑供应商提供的启动脚本。
许多开发人员都熟悉Java API (javadocs),但很多时候忽略了文档的其余部分。它包含许多有趣的信息:http://download.oracle.com/javase/6/docs/technotes/guides/
更新:如果您不想使用代理来解析一些本地/内网主机,请查看来自@Tomalak的评论:
不要忘记http。nonProxyHosts财产!
-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.example.com|etc"
下面展示了如何在Java中通过命令行设置具有代理用户和代理密码的代理,这是一种非常常见的情况。首先,您不应该在代码中保存密码和主机,这是一个规则。
在命令行中使用-D传递系统属性,并使用system在代码中设置它们。setProperty("name", "value")是等价的。
但是请注意
工作的例子:
C:\temp>java -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps.proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit com.andreas.JavaNetHttpConnection
但是下面的方法不起作用:
C:\temp>java com.andreas.JavaNetHttpConnection -Dhttps.proxyHost=host -Dhttps.proxyPort=port -Dhttps=proxyUser=user -Dhttps.proxyPassword="password" -Djavax.net.ssl.trustStore=c:/cacerts -Djavax.net.ssl.trustStorePassword=changeit
唯一的区别是系统属性的位置!(上课前后)
如果你的密码中有特殊字符,你可以把它放在引号中“@MyPass123%”,就像上面的例子一样。
访问HTTPS服务时,必须使用HTTPS协议。proxyHost, https。proxyPort等等。
如果访问HTTP服务,必须使用HTTP。proxyHost, http。proxyPort等等。
使用系统代理设置:
java -Djava.net.useSystemProxies=true ...
或编程:
System.setProperty("java.net.useSystemProxies", "true");
来源:http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
你可以通过编程的方式设置这些标志:
if (needsProxy()) {
System.setProperty("http.proxyHost",getProxyHost());
System.setProperty("http.proxyPort",getProxyPort());
} else {
System.setProperty("http.proxyHost","");
System.setProperty("http.proxyPort","");
}
只要从方法needsProxy(), getProxyHost()和getProxyPort()中返回正确的值,您就可以随时调用此代码片段。
以编程方式设置HTTP/HTTPS和/或SOCKS代理:
...
public void setProxy() {
if (isUseHTTPProxy()) {
// HTTP/HTTPS Proxy
System.setProperty("http.proxyHost", getHTTPHost());
System.setProperty("http.proxyPort", getHTTPPort());
System.setProperty("https.proxyHost", getHTTPHost());
System.setProperty("https.proxyPort", getHTTPPort());
if (isUseHTTPAuth()) {
String encoded = new String(Base64.encodeBase64((getHTTPUsername() + ":" + getHTTPPassword()).getBytes()));
con.setRequestProperty("Proxy-Authorization", "Basic " + encoded);
Authenticator.setDefault(new ProxyAuth(getHTTPUsername(), getHTTPPassword()));
}
}
if (isUseSOCKSProxy()) {
// SOCKS Proxy
System.setProperty("socksProxyHost", getSOCKSHost());
System.setProperty("socksProxyPort", getSOCKSPort());
if (isUseSOCKSAuth()) {
System.setProperty("java.net.socks.username", getSOCKSUsername());
System.setProperty("java.net.socks.password", getSOCKSPassword());
Authenticator.setDefault(new ProxyAuth(getSOCKSUsername(), getSOCKSPassword()));
}
}
}
...
public class ProxyAuth extends Authenticator {
private PasswordAuthentication auth;
private ProxyAuth(String user, String password) {
auth = new PasswordAuthentication(user, password == null ? new char[]{} : password.toCharArray());
}
protected PasswordAuthentication getPasswordAuthentication() {
return auth;
}
}
...
请记住,HTTP代理和SOCKS代理在网络堆栈中的不同级别上操作,因此您可以使用其中一个或另一个,也可以同时使用两者。