0

How can I have many JavaFX WebView components each with its own private cookie-based session on the same server, e.g. from a UI with many tabs?

As a use case, run the following SSCCE and login to a site (I have been using https://mail.google.com/) from the "Browser 1" tab. Open the same site from the "Browser 2" tab, and you will see the session from "Browser 1". (NOTE: You have to enter the full address, with the protocol prefix - http:// - and press the "Go" button - ENTER will not work.)

EDIT: Using the engine.userDataDirectory property does not work either.

import javafx.application.Application;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.concurrent.Worker.State;

public class TwoBrowserTabs extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        TabPane tabPane = new TabPane();

        Tab tab1 = new Tab();
        tab1.setText("Browser 1");
        tab1.setContent(makeBrowserTab("browser1"));
        tabPane.getTabs().add(tab1);

        Tab tab2 = new Tab();
        tab2.setText("Browser 2");
        tab2.setContent(makeBrowserTab("browser2"));
        tabPane.getTabs().add(tab2);

        Scene scene = new Scene(tabPane);
        primaryStage.setTitle("Two browsers");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private Node makeBrowserTab(String identifier) {
        BorderPane borderPane = new BorderPane();
        TextField address = new TextField();
        HBox.setHgrow(address, Priority.ALWAYS);
        Button go = new Button();
        go.setText("Go");
        HBox hbox = new HBox();
        hbox.getChildren().add(address);
        hbox.getChildren().add(go);
        WebView browser = new WebView();
        browser.setPrefSize(960, 640);
        borderPane.setTop(hbox);
        borderPane.setCenter(browser);

        WebEngine engine = browser.getEngine();

        // EDIT: Does not work either
        engine.setUserDataDirectory(new File(System.getProperty("user.home") + File.separator + "TwoBrowserTabs" + File.separator + identifier));

        // Let the button reflect the state of the loader,
        // so as to have a minimalistic feedback.
        engine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
            if( newState == State.READY || newState == State.SUCCEEDED ) {
                go.setDisable(false);
                go.setText("Go");
            }
            else if( newState == State.FAILED || newState == State.CANCELLED ) {
                go.setDisable(false);
                go.setText("Go (!)");
            }
            else {
                go.setDisable(true);
                go.setText("Go");
            }
        });

        go.setOnAction(event -> {
            engine.load(address.getText());
        });

        return borderPane;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90
  • 1
    Did you see this related question ? http://stackoverflow.com/questions/15583057/using-a-hacked-cookiemanager-to-allow-2-different-instances-of-webview-with-diff – gontard Feb 26 '15 at 14:03
  • @gontard Thank you, I had not seen this. It seems to be the same problem, and that too has no solution. *Unless you can reliably relate a thread with a `WebView` instance, the `InMemory` (i.e. `ThreadLocal`) cookie store has no meaning*, as far as I understand. – Nikos Paraskevopoulos Feb 26 '15 at 14:37
  • Yes, there is no answer. But the solution explored by the OP looks interresting. Having a custom CookieManager which dispatch to the right CookieStore. The remaining question: is there a way to identify which WebView make the http call – gontard Feb 26 '15 at 14:44
  • 1
    This may be possible in a future javafx version: [WebNode should store and manage cookies independently from default CookieHandler](https://javafx-jira.kenai.com/browse/RT-12202) – gontard Feb 26 '15 at 14:49
  • The link above is dead now; replacement [here](https://bugs.openjdk.java.net/browse/JDK-8090959). – Nikos Paraskevopoulos Sep 06 '21 at 10:13

1 Answers1

0

I think you can get help from answer in below link: Clear the session/cache/cookie in the JavaFX WebView

Also if the server part is under your control, you can make some session settings in that so as to not maintain sessions & you can also stop cookies from storing on client side.

Community
  • 1
  • 1
Atanu Pal
  • 135
  • 2
  • 11
  • Thank you for your response. I *have* seen this answer and it is useful to an extent. However it addresses the problem of clearing the (single) cache, *not* how to use *separate* caches per `WebView` instance. To state the problem differently, how can the `CookieManager` return a *different* `CookieStore` depending on which `WebView` initiated the HTTP call? – Nikos Paraskevopoulos Feb 26 '15 at 08:45
  • Also the server cannot be changed. – Nikos Paraskevopoulos Feb 26 '15 at 08:58