Настройка JVM / JRE для автоматического использования Windows Proxy - PullRequest
31 голосов
/ 18 декабря 2008

Я видел вопрос о настройке прокси для JVM, но я хочу спросить, как можно использовать уже настроенный прокси (в Windows).

Вот демонстрация моей проблемы:

  1. Перейдите в свою Панель управления-> Java и установите адрес прокси.
  2. Запустите следующий простой код апплета (я использую Eclipse IDE):
import java.awt.Graphics;
import javax.swing.JApplet;
import java.util.*;

public class Stacklet extends JApplet {
    private String message;
    public void init(){
        Properties props = System.getProperties();
        message = props.getProperty("http.proxyHost", "NONE");      
        message = (message.length() == 0)? "NONE": message;
    }

    public void paint(Graphics g)
    {
        g.drawString(message, 20, 20);
    }
}

Апплет отображает «НЕТ» независимо от настроек, которые вы установили на панели управления Java. Лучше всего было бы, если бы я мог определить параметры прокси-сервера Windows (обычно устанавливаемые в Internet Explorer), но выполнение дополнительного шага настройки в панели управления Java все равно было бы приемлемым решением.

Спасибо!

Ответы [ 6 ]

38 голосов
/ 19 декабря 2008

Можно определить прокси с помощью класса ProxySelector и назначить системный прокси, назначив переменные среды с помощью метода setProperty класса System :

System.setProperty("java.net.useSystemProxies", "true");
System.out.println("detecting proxies");
List l = null;
try {
    l = ProxySelector.getDefault().select(new URI("http://foo/bar"));
} 
catch (URISyntaxException e) {
    e.printStackTrace();
}
if (l != null) {
    for (Iterator iter = l.iterator(); iter.hasNext();) {
        java.net.Proxy proxy = (java.net.Proxy) iter.next();
        System.out.println("proxy type: " + proxy.type());

        InetSocketAddress addr = (InetSocketAddress) proxy.address();

        if (addr == null) {
            System.out.println("No Proxy");
        } else {
            System.out.println("proxy hostname: " + addr.getHostName());
            System.setProperty("http.proxyHost", addr.getHostName());
            System.out.println("proxy port: " + addr.getPort());
            System.setProperty("http.proxyPort", Integer.toString(addr.getPort()));
        }
    }
}
10 голосов
/ 17 августа 2011

Я обнаружил странное поведение, экспериментирующее с предлагаемым кодом здесь.

Похоже, что после установки ProxySelector по умолчанию обычный код сокета (например, создание нового сокета) больше не работает, потому что он пытается использовать сервер socks (не уверен, почему он это сделал, но для меня оно делает).

Так что если вы при звонке

Socket socket = new Socket(host, port);

вы получаете такое SocketException:

java.net.SocketException: Malformed reply from SOCKS server
    at java.net.SocksSocketImpl.readSocksReply(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)

, затем попробуйте установить значение по умолчанию ProxySelector равным нулю:

ProxySelector.setDefault(null);

Для меня это привело к следующему небольшому классу Java, который я теперь использую, чтобы просто получить настройки прокси-сервера системы, не влияя на дальнейшее использование Sockets () приложения, и в то же время правильно настроить систему для использования прокси: 1014 *

public class ProxyConfig {

  private static String host;
  private static int port;

  public static void init() {
    System.setProperty("java.net.useSystemProxies", "true");
    Proxy proxy = getProxy();
    if (proxy != null) {
      InetSocketAddress addr = (InetSocketAddress) proxy.address();
      host = addr.getHostName();
      port = addr.getPort();

      System.setProperty("java.net.useSystemProxies", "false");
      System.setProperty("http.proxyHost", host);
      System.setProperty("http.proxyPort", ""+port);

    }
    System.setProperty("java.net.useSystemProxies", "false");
  }

  public static String getHost() {
    return host;
  }

  public static int getPort() {
    return port;
  }

  private static Proxy getProxy() {
    List<Proxy> l = null;
    try {
      ProxySelector def = ProxySelector.getDefault();

      l = def.select(new URI("http://foo/bar"));
      ProxySelector.setDefault(null);
    } catch (Exception e) {
      e.printStackTrace();
    }
    if (l != null) {
      for (Iterator<Proxy> iter = l.iterator(); iter.hasNext();) {
        java.net.Proxy proxy = iter.next();
        return proxy;
      }
    }
    return null;
  }
}
9 голосов
/ 10 декабря 2015

Это может быть немного поздно, но я сталкиваюсь с той же проблемой. Я исправил это, используя -Djava.net.useSystemProxies = true в качестве аргументов jvm.

"Обратите внимание, что это свойство проверяется только один раз при запуске."

Это свойство устанавливается при запуске, поэтому оно не изменится при запуске приложения.

Надеюсь, это поможет.

Ссылка: https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html

4 голосов
/ 07 декабря 2010

java.net.URL.openStream() является сокращением для java.net.URL.openConnection().getInputStream().

2 голосов
/ 30 сентября 2010

ОБНОВЛЕНИЕ: вам нужно, чтобы системное свойство java.net.useSystemProxies было установлено на true , чтобы мое решение работало ниже.

Если вы используете java.net.URL.openStream() для получения InputStream для содержимого веб-ресурса, вы автоматически получаете тот же прокси-сервер, что и Internet Explorer для этого URL.

Нет необходимости переходить на панель управления Java или отображать используемый прокси.

1 голос
/ 02 ноября 2018
try{
    System.setProperty("java.net.useSystemProxies", "true");
    String prx = ProxySelector.getDefault().select(new URI("http://www.google.com")).get(0).address().toString();
    JOptionPane.showMessageDialog(null, prx);
} catch(Exception e){
    JOptionPane.showMessageDialog(null, "no proxy");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...