Set proxy on JavaFX WebEngine?

2020-02-05 09:15发布

问题:

How can I set a proxy per WebView instance?

This is what I have so far:

public void start(Stage stage) {
    StackPane root = new StackPane();

    WebView view = new WebView();
    WebEngine engine = view.getEngine();
    engine.load("https://www.google.com");
    root.getChildren().add(view);

    Scene scene = new Scene(root, 960, 640);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) throws IOException {
    Application.launch(args);
}

That launches a window with the google page just fine.

However how can I set a proxy? Not the VM system proxy, but a proxy per WebView window.

回答1:

From the deployment overview:

3.2.3 Built-In Proxy Support

Properly packaged JavaFX application have proxy settings initialized according to Java Runtime configuration settings. By default, this means proxy settings will be taken from the current browser if the application is embedded into a web page, or system proxy settings will be used. Proxy settings are initialized by default in all execution modes.

It might not be possible to set per WebView instance. One hack comes to mind, but I really wouldn't want to do it - extend WebView such that whenever the user (and scripts and such in the WebView) interact with it, it calls System.setProperty("http.proxy",this.myProxy). Something like:

class KludgeWebView extends WebView {
  String myProxy;
  String myProxyPort;
  String sysProxy;
  String sysProxyPort;

  KludgeWebView()
  {
    super();

    sysProxy = System.getProperty("http.proxy");
    sysProxyPort = System.getProperty("http.proxyPort");
  }

  public void load(String url)
  {
    useProxy();
    super.load(url);
    revertProxy();
  }

  public void useProxy()
  {
    System.setProperty("http.proxy",myProxy);
    System.setProperty("http.proxyPort", myProxyPort);
  }

  public void revertProxy()
  {
    System.setProperty("http.proxy",sysProxy);
    System.setProperty("http.proxyPort", sysProxyPort);    
  }
}

However, this seems very messy to me. It might miss things like a user clicking on a link inside the WebView, or scripts doing things like XmlHttpRequest. I wouldn't recommend this unless you are left with no other options.



回答2:

http.proxy does not work, i had to use http.proxyHost.

System.setProperty("http.proxyHost","proxy.esrf.fr");
System.setProperty("http.proxyPort","3128");


回答3:

I have tried all the answers above but none of them worked for me. I have also tried to change the system setting using

System.setProperty("http.proxyHost","your proxy address");
System.setProperty("http.proxyPort","your port");

But that didn't work, either. The only solution I found to work is make your Java application to run a command with

Runtime.getRuntime().exec(CHANGE_PROXY_CMD);

That will change the system proxy setting by modifying the registry settings.Any way it is not possible to set proxy per web instance as it is clearly told in javafx documentation.

There are three commands

  • Enable proxy server settings
  • Change proxy server settings
  • Disable proxy server settings

That's it.

public void changeProxySettings(String ip, String port) {

    StringBuffer output = new StringBuffer();

    System.setProperty("java.net.useSystemProxies", "true");

    String ENABLE_PROXY_CMD = " reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" \n" + "    /v ProxyEnable /t REG_DWORD /d 1 /f";

    String CHANGE_PROXY_CMD = "reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" \n" + "    /v ProxyServer /t REG_SZ /d " + ip + ":" + port + "  /f";

    String DISABLE_PROXY_CMD = "reg add \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\" \n" + "    /v ProxyEnable /t REG_DWORD /d 0 /f";

    Process processEnableProxy, processChangeProxy, processDisableProxy;
    try {
        processEnableProxy = Runtime.getRuntime().exec(ENABLE_PROXY_CMD);

        processEnableProxy.waitFor();//makes the current thread to wait until system settings are applied

        processChangeProxy = Runtime.getRuntime().exec(CHANGE_PROXY_CMD);

        processChangeProxy.waitFor();

        BufferedReader reader = new BufferedReader(new InputStreamReader(processEnableProxy.getInputStream()));

        String line = "";
        while ((line = reader.readLine()) != null) {
            output.append(line + "\n");
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

    System.out.println(output.toString());

}


回答4:

You should use

System.setProperty("http.proxyHost","your proxy address"); System.setProperty("http.proxyPort","your port");

for http sites and

System.setProperty("https.proxyHost","your proxy address"); System.setProperty("https.proxyPort","your port");

for https sites