Подтвердить что ты не робот

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

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

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

  •   
  • Перейдите на панель управления → Java и установите адрес прокси.  
  • Запустите следующий простой код апплета (я использую 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);
    }
}

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

Спасибо!

4b9b3361

Ответ 1

Можно определить прокси-сервер, используя класс 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()));
        }
    }
}

Ответ 2

Я нашел странное поведение, экспериментируя с предлагаемым кодом здесь.

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

Итак, если вы звоните

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 по умолчанию значение null:

ProxySelector.setDefault(null);

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

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;
  }
}

Ответ 3

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

-Djava.net.useSystemProxies=true

Теперь обратите внимание, что это свойство устанавливается только один раз при запуске, поэтому оно не может измениться при запуске приложения. С https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html#Proxies:

java.net.useSystemProxies (по умолчанию: false)... Обратите внимание, что это свойство проверяется только один раз при запуске.

Ответ 4

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

Ответ 5

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

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

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

Ответ 6

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");
}