很多时候,Java应用程序需要连接到Internet。最常见的例子发生在读取XML文件并需要下载其模式时。
我在代理服务器后面。如何将JVM设置为使用代理?
很多时候,Java应用程序需要连接到Internet。最常见的例子发生在读取XML文件并需要下载其模式时。
我在代理服务器后面。如何将JVM设置为使用代理?
当前回答
以编程方式设置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代理在网络堆栈中的不同级别上操作,因此您可以使用其中一个或另一个,也可以同时使用两者。
其他回答
从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"
这是一个对我有用的完整示例-注意,对于HTTPS有单独的属性(根据https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html)。
下面的代码向https://api.myip.com API发送请求并打印响应。
public static void main(String[] args) throws IOException {
System.setProperty("java.net.useSystemProxies", "true");
final String proxyUser = "proxy-user";
final String proxyPass = "password123";
final String host = "some.proxy.io";
final Integer port = 50201;
// http
System.setProperty("http.proxyHost",host);
System.setProperty("http.proxyPort", String.valueOf(port));
System.setProperty("http.proxyUser", proxyUser);
System.setProperty("http.proxyPassword", proxyPass);
// https
System.setProperty("https.proxyHost",host);
System.setProperty("https.proxyPort", String.valueOf(port));
System.setProperty("https.proxyUser", proxyUser);
System.setProperty("https.proxyPassword", proxyPass);
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
System.setProperty("jdk.https.auth.tunneling.disabledSchemes", "");
Authenticator.setDefault(new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(proxyUser, proxyPass.toCharArray());
}
}
);
// create and send a https request to myip.com API
URL url = new URL("https://api.myip.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
int status = connection.getResponseCode();
// read the response
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String responseLine;
StringBuffer responseContent = new StringBuffer();
while ((responseLine = in.readLine()) != null)
responseContent.append(responseLine);
in.close();
connection.disconnect();
// print the response
System.out.println(status);
System.out.println(responseContent);
}
我认为配置WINHTTP也可以。
包括Windows更新在内的许多程序在代理后都有问题。通过设置WINHTTP总能解决这类问题
以编程方式设置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代理在网络堆栈中的不同级别上操作,因此您可以使用其中一个或另一个,也可以同时使用两者。
如果你想要“Socks Proxy”,通知“socksProxyHost”和“socksProxyPort”虚拟机参数。
e.g.
java -DsocksProxyHost=127.0.0.1 -DsocksProxyPort=8080 org.example.Main