很多时候,Java应用程序需要连接到Internet。最常见的例子发生在读取XML文件并需要下载其模式时。
我在代理服务器后面。如何将JVM设置为使用代理?
很多时候,Java应用程序需要连接到Internet。最常见的例子发生在读取XML文件并需要下载其模式时。
我在代理服务器后面。如何将JVM设置为使用代理?
当前回答
将usesystemagents属性设置为true。例如,您可以通过JAVA_TOOL_OPTIONS环境变量来设置它。例如,在Ubuntu中,你可以在.bashrc中添加以下代码行:
export JAVA_TOOL_OPTIONS+=" - djava.net.usesystemagents =true"
其他回答
在连接到代理后面的URL之前添加此选项。
System.getProperties().put("http.proxyHost", "someProxyURL");
System.getProperties().put("http.proxyPort", "someProxyPort");
System.getProperties().put("http.proxyUser", "someUserName");
System.getProperties().put("http.proxyPassword", "somePassword");
这是一个小更新,但是从Java 7开始,现在可以通过编程方式创建代理连接,而不是通过系统属性。这可能是有用的,如果:
代理需要在程序运行时动态旋转 需要使用多个并行代理 或者只是让你的代码更干净:)
这是groovy中一个人为的例子:
// proxy configuration read from file resource under "proxyFileName"
String proxyFileName = "proxy.txt"
String proxyPort = "1234"
String url = "http://www.promised.land"
File testProxyFile = new File(proxyFileName)
URLConnection connection
if (!testProxyFile.exists()) {
logger.debug "proxyFileName doesn't exist. Bypassing connection via proxy."
connection = url.toURL().openConnection()
} else {
String proxyAddress = testProxyFile.text
connection = url.toURL().openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, proxyPort)))
}
try {
connection.connect()
}
catch (Exception e) {
logger.error e.printStackTrace()
}
全部参考: http://docs.oracle.com/javase/7/docs/technotes/guides/net/proxies.html
下面展示了如何在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等等。
读取一个XML文件,并需要下载它的模式
如果您依赖于通过internet检索模式或dtd,那么您正在构建一个缓慢、频繁且脆弱的应用程序。当托管文件的远程服务器发生计划内或计划外停机时,会发生什么?你的应用程序崩溃了。这样可以吗?
看到http://xml.apache.org/commons/components/resolver/resolver-article.html s.catalog.files
模式和类似的URL最好被认为是唯一标识符。而不是远程访问文件的请求。在“XML目录”上做一些谷歌搜索。XML目录允许您在本地托管这些资源,从而解决了慢、多和脆弱的问题。
它基本上是远程内容的永久缓存副本。这是可以的,因为远程内容永远不会改变。如果有更新,也会是另一个网址。使得在互联网上实际检索资源变得特别愚蠢。
最近,我发现了允许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;
}
}
之后,可以通过java.net.ProxySelector将代理设置提供给Java API。
这种方法的唯一问题是你需要在bootclasspath中使用deploy.jar启动JVM,例如java -Xbootclasspath/a:"%JAVA_HOME%\jre\lib\deploy.jar" -jar my.jar。如果有人知道如何克服这个限制,请告诉我。