Несколько компонентов WebView, каждый с отдельным сеансом

Как я могу иметь много компонентов JavaFX WebView, каждый из которых имеет свой собственный сеанс на основе файлов cookie на одном сервере, например. из пользовательского интерфейса со многими вкладками?

В качестве примера использования запустите следующий SSCCE и войдите на сайт (я использовал https://mail.google.com/) на вкладке "Браузер 1". Откройте тот же сайт из вкладки «Браузер 2», и вы увидите сессию из «Браузера 1». (ПРИМЕЧАНИЕ: необходимо ввести полный адрес с префиксом протокола — http:// — и нажать кнопку «Перейти» — ENTER не сработает.)

EDIT: использование свойства engine.userDataDirectory также не работает.

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

person Nikos Paraskevopoulos    schedule 22.02.2015    source источник
comment
Вы видели этот связанный вопрос? stackoverflow.com/questions/15583057/   -  person gontard    schedule 26.02.2015
comment
@gontard Спасибо, я этого не видел. Похоже, это та же проблема, и она тоже не имеет решения. Если вы не можете надежно связать поток с экземпляром WebView, хранилище файлов cookie InMemory (то есть ThreadLocal) не имеет смысла, насколько я понимаю.   -  person Nikos Paraskevopoulos    schedule 26.02.2015
comment
Да нет ответа. Но решение, изученное ОП, выглядит интересным. Имея собственный CookieManager, который отправляет в правильный CookieStore. Оставшийся вопрос: есть ли способ определить, какой WebView делает http-вызов   -  person gontard    schedule 26.02.2015
comment
Это может быть возможно в будущей версии javafx: WebNode должен хранить файлы cookie и управлять ими независимо от CookieHandler по умолчанию.   -  person gontard    schedule 26.02.2015


Ответы (1)


Я думаю, вы можете получить помощь из ответа по ссылке ниже: сеанс/кеш/куки в JavaFX WebView

Кроме того, если серверная часть находится под вашим контролем, вы можете сделать некоторые настройки сеанса, чтобы не поддерживать сеансы, а также запретить сохранение файлов cookie на стороне клиента.

person Atanu Pal    schedule 26.02.2015
comment
Благодарю за ваш ответ. Я видел этот ответ, и он в некоторой степени полезен. Однако он решает проблему очистки (одного) кеша, а не как использовать отдельные кеши для каждого экземпляра WebView. Чтобы сформулировать проблему по-другому, как CookieManager может вернуть другой CookieStore в зависимости от того, какой WebView инициировал HTTP-вызов? - person Nikos Paraskevopoulos; 26.02.2015
comment
Также сервер не может быть изменен. - person Nikos Paraskevopoulos; 26.02.2015