我正在尝试在我的用户界面(在Java 1.6.0.23上运行的Eclipse应用程序)中更改JVM的代理设置
if (isUseProxy()) {
System.setProperty("java.net.useSystemProxies", "true");
System.setProperty("http.proxyHost", getProxyHost());
System.setProperty("http.proxyPort", getProxyPort());
System.setProperty("https.proxyHost", getProxyHost());
System.setProperty("https.proxyPort", getProxyPort());
..........
} else {
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
}
问题是在JVM重新启动之前不会使用新的代理服务器值,它会在Java中缓存。
Java版:
java.runtime.version=1.6.0_26-b03
java.specification.name=Java Platform API Specification
java.specification.vendor=Sun Microsystems Inc.
更新: 魔术继续...我试图隔离问题,以弄清楚Java如何神奇地与system.properties一起工作。 看起来Java在某些随机情况下会忽略无效的代理服务器设置。此测试失败:
import org.junit.Test;
import java.io.IOException;
import java.net.*;
import static org.junit.Assert.fail;
public class ProxySetTest {
@Test
public void verifyProxyIsNotCachedInJVM() throws IOException {
tryConnectionToGoogleCom();
System.setProperty("http.proxyHost", getInvalidProxyHost());
System.setProperty("http.proxyPort", getInvalidProxyPort()+"");
System.setProperty("https.proxyHost", getInvalidProxyHost());
System.setProperty("https.proxyPort", getInvalidProxyPort()+"");
// Next connection will be through the invalid proxy. must fail?
try {
tryConnectionToGoogleCom();
fail("must have failed with an exception because of invalid proxy setting");
} catch (Exception e) {
System.out.println("received exception: " + e);
}
// clear the proxy setting and try connecting again - must succeed
System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
System.clearProperty("https.proxyHost");
System.clearProperty("https.proxyPort");
// and without proxy again
tryConnectionToGoogleCom();
}
private void tryConnectionToGoogleCom() throws IOException {
URL url = new URL("http://google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
}
private int getInvalidProxyPort() {
return 1234;
}
private String getInvalidProxyHost() {
return "asd";
}
}
答案 0 :(得分:6)
所以我遇到了完全相同的问题,并将其跟踪到轴缓存信息。
位于org.apache.axis.components.net.TransportClientPropertiesFactory
有问题的方法是:
public static TransportClientProperties create(String protocol)
{
TransportClientProperties tcp =
(TransportClientProperties)cache.get(protocol);
if (tcp == null) {
tcp = (TransportClientProperties)
AxisProperties.newInstance(TransportClientProperties.class,
(Class)defaults.get(protocol));
if (tcp != null) {
cache.put(protocol, tcp);
}
}
return tcp;
}
在第一次调用时,将使用代理的当前JVM设置创建tcp对象。在后续调用中,它会提取缓存版本,因此即使您更改了JVM中的代理设置,也无关紧要。想看看我是否能找到清除缓存的方法。
答案 1 :(得分:2)
package com.alskor;
import org.junit.Test;
import java.io.IOException;
import java.net.*;
import static org.junit.Assert.fail;
public class ProxySetTest {
@Test
public void verifyProxyIsNotCachedInJVM() throws IOException {
tryConnectionToGoogleCom();
ProxySelector savedSelector = ProxySelector.getDefault();
java.net.ProxySelector.setDefault(new FixedProxySelector(getInvalidProxyHost(), getInvalidProxyPort()));
// Next connection will be through the invalid proxy. must fail?
try {
tryConnectionToGoogleCom();
fail("must have failed with an exception because of invalid proxy setting");
} catch (Exception e) {
System.out.println("received exception: " + e);
}
// clear the proxy setting and try connecting again - must succeed
java.net.ProxySelector.setDefault(savedSelector);
// and without proxy again
tryConnectionToGoogleCom();
}
private void tryConnectionToGoogleCom() throws IOException {
URL url = new URL("http://google.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
}
private int getInvalidProxyPort() {
return 1234;
}
private String getInvalidProxyHost() {
return "asd";
}
}
package com.alskor;
import sun.misc.RegexpPool;
import java.io.IOException;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
public class FixedProxySelector extends ProxySelector {
private final String host;
private final int port;
public FixedProxySelector(String host, int port) {
this.host = host;
this.port = port;
}
@Override
public java.util.List<Proxy> select(URI uri) {
if (uri == null) {
throw new IllegalArgumentException("URI can't be null.");
}
List<Proxy> proxies = new ArrayList<Proxy>();
SocketAddress addr = new InetSocketAddress(host, port);
proxies.add(new Proxy(Proxy.Type.SOCKS, addr));
proxies.add(new Proxy(Proxy.Type.HTTP, addr));
return proxies;
}
@Override
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
if (uri == null || sa == null || ioe == null) {
throw new IllegalArgumentException("Arguments can't be null.");
}
throw new RuntimeException(ioe.toString(), ioe);
}
}
答案 2 :(得分:1)
将java.net.Proxy对象传递给URL.openConnection(代理)方法。 您可以使用Proxy.NO_PROXY进行直接连接。或者像这样创建新的代理:
new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8080))
以下是完整的示例:
public class TestConnectOverProxy {
static class Connector {
private Proxy proxy = Proxy.NO_PROXY;
public void setProxy(Proxy proxy) {
this.proxy = proxy;
}
/**
* This method works with java.net.Proxy field of the Connector class
* as described
* <a href="http://www.rgagnon.com/javadetails/java-0085.html">here</a>
*/
public String getContent(URL url) throws IOException {
HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
conn.connect();
System.out.println(conn.getRequestMethod());
System.out.println(conn.getResponseCode());
return IOUtils.toString(conn.getInputStream());
}
}
@Test
public void test() throws IOException {
URL url = new URL("http://www.google.com");
Connector connector = new Connector();
//connect directly
connector.setProxy(Proxy.NO_PROXY);
System.out.println(connector.getContent(url));
//connect over proxy
connector.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 8080)));
System.out.println(connector.getContent(url));
}
}