Java 如何设置 JVM 使用的代理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/120797/
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
How do I set the proxy to be used by the JVM
提问by Leonel
Many times, a Java app needs to connect to the Internet. The most common example happens when it is reading an XML file and needs to download its schema.
很多时候,Java 应用程序需要连接到 Internet。最常见的示例发生在读取 XML 文件并需要下载其架构时。
I am behind a proxy server. How can I set my JVM to use the proxy ?
我在代理服务器后面。如何设置我的 JVM 以使用代理?
采纳答案by Leonel
From the Java documentation (notthe javadoc API):
从 Java 文档(不是javadoc API):
http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
http://download.oracle.com/javase/6/docs/technotes/guides/net/proxies.html
Set the JVM flags http.proxyHost
and http.proxyPort
when starting your JVM on the command line.
This is usually done in a shell script (in Unix) or bat file (in Windows). Here's the example with the Unix shell script:
在命令行上设置 JVM 标志http.proxyHost
和http.proxyPort
启动 JVM 时。这通常在 shell 脚本(在 Unix 中)或 bat 文件(在 Windows 中)中完成。这是 Unix shell 脚本的示例:
JAVA_FLAGS=-Dhttp.proxyHost=10.0.0.100 -Dhttp.proxyPort=8800
java ${JAVA_FLAGS} ...
When using containers such as JBoss or WebLogic, my solution is to edit the start-up scripts supplied by the vendor.
在使用JBoss或WebLogic等容器时,我的解决方案是编辑厂商提供的启动脚本。
Many developers are familiar with the Java API (javadocs), but many times the rest of the documentation is overlooked. It contains a lot of interesting information: http://download.oracle.com/javase/6/docs/technotes/guides/
许多开发人员熟悉 Java API (javadocs),但很多时候忽略了文档的其余部分。它包含很多有趣的信息:http: //download.oracle.com/javase/6/docs/technotes/guides/
Update :If you do not want to use proxy to resolve some local/intranet hosts, check out the comment from @Tomalak:
更新:如果您不想使用代理来解析某些本地/内联网主机,请查看@Tomalak 的评论:
Also don't forget the http.nonProxyHosts property!
也不要忘记 http.nonProxyHosts 属性!
-Dhttp.nonProxyHosts="localhost|127.0.0.1|10.*.*.*|*.foo.com??|etc"
回答by GHad
You can set those flags programmatically this way:
您可以通过以下方式以编程方式设置这些标志:
if (needsProxy()) {
System.setProperty("http.proxyHost",getProxyHost());
System.setProperty("http.proxyPort",getProxyPort());
} else {
System.setProperty("http.proxyHost","");
System.setProperty("http.proxyPort","");
}
Just return the right values from the methods needsProxy()
, getProxyHost()
and getProxyPort()
and you can call this code snippet whenever you want.
单从方法返回正确的价值观needsProxy()
,getProxyHost()
并且getProxyPort()
你可以打电话,只要你想这个代码片断。
回答by John M
reading an XML file and needs to download its schema
读取 XML 文件并需要下载其架构
If you are counting on retrieving schemas or DTDs over the internet, you're building a slow, chatty, fragile application. What happens when that remote server hosting the file takes planned or unplanned downtime? Your app breaks. Is that OK?
如果您指望通过 Internet 检索模式或 DTD,那么您正在构建一个缓慢、健谈、脆弱的应用程序。当托管文件的远程服务器出现计划内或计划外停机时会发生什么?您的应用程序中断。这可以吗?
See http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files
请参阅http://xml.apache.org/commons/components/resolver/resolver-article.html#s.catalog.files
URL's for schemas and the like are best thought of as unique identifiers. Not as requests to actually access that file remotely. Do some google searching on "XML catalog". An XML catalog allows you to host such resources locally, resolving the slowness, chattiness and fragility.
模式等的 URL 最好被认为是唯一标识符。不是作为远程实际访问该文件的请求。在“XML 目录”上进行一些谷歌搜索。XML 目录允许您在本地托管此类资源,从而解决缓慢、繁琐和脆弱的问题。
It's basically a permanently cached copy of the remote content. And that's OK, since the remote content will never change. If there's ever an update, it'd be at a different URL. Making the actual retrieval of the resource over the internet especially silly.
它基本上是远程内容的永久缓存副本。没关系,因为远程内容永远不会改变。如果有更新,它将位于不同的 URL。使通过互联网实际检索资源变得特别愚蠢。
回答by Alex. S.
You can set some properties about the proxy server as jvm parameters
您可以将有关代理服务器的一些属性设置为 jvm 参数
-Dhttp.proxyPort=8080, proxyHost, etc.
-Dhttp.proxyPort=8080、proxyHost等
but if you need pass through an authenticating proxy, you need an authenticator like this example:
但是如果你需要通过一个身份验证代理,你需要一个像这个例子一样的身份验证器:
ProxyAuthenticator.java
ProxyAuthenticator.java
import java.net.*;
import java.io.*;
public class ProxyAuthenticator extends Authenticator {
private String userName, password;
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(userName, password.toCharArray());
}
public ProxyAuthenticator(String userName, String password) {
this.userName = userName;
this.password = password;
}
}
Example.java
例子.java
import java.net.Authenticator;
import ProxyAuthenticator;
public class Example {
public static void main(String[] args) {
String username = System.getProperty("proxy.authentication.username");
String password = System.getProperty("proxy.authentication.password");
if (username != null && !username.equals("")) {
Authenticator.setDefault(new ProxyAuthenticator(username, password));
}
// here your JVM will be authenticated
}
}
Based on this reply: http://mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E
基于此回复:http: //mail-archives.apache.org/mod_mbox/jakarta-jmeter-user/200208.mbox/%3C494FD350388AD511A9DD00025530F33102F1DC2C@MMSX006%3E
回答by Chris Carruthers
To set an HTTP/HTTPS and/or SOCKS proxy programmatically:
以编程方式设置 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;
}
}
...
Remember that HTTP proxies and SOCKS proxies operate at different levels in the network stack, so you can use one or the other or both.
请记住,HTTP 代理和 SOCKS 代理在网络堆栈中的不同级别运行,因此您可以使用其中一个或两者。
回答by Chris Carruthers
You can utilize the http.proxy* JVM variables if you're within a standalone JVM but you SHOULD NOT modify their startup scripts and/or do this within your application server (except maybe jboss or tomcat). Instead you should utilize the JAVA Proxy API (not System.setProperty) or utilize the vendor's own configuration options. Both WebSphere and WebLogic have very defined ways of setting up the proxies that are far more powerful than the J2SE one. Additionally, for WebSphere and WebLogic you will likely break your application server in little ways by overriding the startup scripts (particularly the server's interop processes as you might be telling them to use your proxy as well...).
如果您在独立的 JVM 中,您可以使用 http.proxy* JVM 变量,但您不应该修改它们的启动脚本和/或在您的应用程序服务器中执行此操作(jboss 或 tomcat 除外)。相反,您应该使用 JAVA 代理 API(而不是 System.setProperty)或使用供应商自己的配置选项。WebSphere 和 WebLogic 都有非常明确的设置代理的方法,这些方法比 J2SE 强大得多。此外,对于 WebSphere 和 WebLogic,您可能会通过覆盖启动脚本(特别是服务器的互操作进程,因为您可能会告诉它们也使用您的代理……)以小方式破坏您的应用程序服务器。
回答by dma_k
Recently I've discovered the way to allow JVM to use browser proxy settings. What you need to do is to add ${java.home}/lib/deploy.jar
to your project and to init the library like the following:
最近我发现了允许 JVM 使用浏览器代理设置的方法。您需要做的是添加${java.home}/lib/deploy.jar
到您的项目并像下面这样初始化库:
import com.sun.deploy.net.proxy.DeployProxySelector;
import com.sun.deploy.services.PlatformType;
import com.sun.deploy.services.ServiceManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public abstract class ExtendedProxyManager {
private static final Log logger = LogFactory.getLog(ExtendedProxyManager.class);
/**
* After calling this method, proxy settings can be magically retrieved from default browser settings.
*/
public static boolean init() {
logger.debug("Init started");
// Initialization code was taken from com.sun.deploy.ClientContainer:
ServiceManager
.setService(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1 ? PlatformType.STANDALONE_TIGER_WIN32
: PlatformType.STANDALONE_TIGER_UNIX);
try {
// This will call ProxySelector.setDefault():
DeployProxySelector.reset();
} catch (Throwable throwable) {
logger.error("Unable to initialize extended dynamic browser proxy settings support.", throwable);
return false;
}
return true;
}
}
Afterwards the proxy settings are available to Java API via java.net.ProxySelector
.
之后,代理设置可通过java.net.ProxySelector
.
The only problem with this approach is that you need to start JVM with deploy.jar
in bootclasspath e.g. java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar
. If somebody knows how to overcome this limitation, let me know.
这种方法的唯一问题是您需要deploy.jar
在引导类路径中启动 JVM,例如java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar
. 如果有人知道如何克服这个限制,请告诉我。
回答by nylas
回答by gr5
To use the system proxy setup:
要使用系统代理设置:
java -Djava.net.useSystemProxies=true ...
Or programatically:
或以编程方式:
System.setProperty("java.net.useSystemProxies", "true");
Source: http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
来源:http: //docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
回答by Pallavi
I am also behind firewall, this worked for me!!
我也在防火墙后面,这对我有用!!
System.setProperty("http.proxyHost", "proxy host addr");
System.setProperty("http.proxyPort", "808");
Authenticator.setDefault(new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("domain\user","password".toCharArray());
}
});
URL url = new URL("http://www.google.com/");
URLConnection con = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));
// Read it ...
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();