存储持久性cookie

时间:2017-03-05 18:58:31

标签: java cookies javafx webview

我目前正在尝试使用javafx,而我正在尝试使用它制作网络浏览器。到目前为止,它的表现相当不错,但令我很恼火的是,我不得不登录每一页。所以我决定使用cookies并将它们存储在一个文件中,所以我不必每次都登录。 我过去5个小时一直试图让这个工作,但我仍然必须每次都登录。这就是我到目前为止所做的:

public class Main extends Application {

public static void main(String[] args) {
    if (!Values.SRCFILE.exists()) {
        Installation.launch(Installation.class, args);
        return;
    }

    launch(args);
}

private Stage stage;
private GridPane pane;

private List<BrowserTab> tabs;

@FXML
private TabPane tabPane;

@FXML
public void initialize() {
    tabs = new ArrayList<>();

    CookieManager manager = new CookieManager();
    manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
    CookieHandler.setDefault(manager);

    Map<String, List<String>> map = new HashMap<>();
    URI uri = null;

    try {
        for (String line : Files.readAllLines(Values.COOKIESFILE.toPath())) {
            String[] values = line.split("\\|");
            URI newUri = new URI(values[0]);

            if (uri == null)
                uri = newUri;

            if (!uri.equals(newUri)) {
                CookieHandler.getDefault().put(uri, map);
                uri = newUri;
                System.out.println(map);
                map = new HashMap<>();
            }

            String[] actualValues = values[1].split(":");

            map.put(actualValues[0], Arrays.asList(actualValues[1].split(";")));
        }

        if (uri != null)
            CookieHandler.getDefault().put(uri, map);
    } catch (IOException | URISyntaxException e) {
        e.printStackTrace();
    }

    System.out.println(map);

    stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
        @Override
        public void handle(WindowEvent event) {
            if (tabs.size() > 1) {
                Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                alert.setTitle("Closing window");
                alert.setHeaderText("");
                alert.setContentText("Are you sure you want to close this window? Doing so will close all open tabs");
                alert.showAndWait();
            }

            //save cookies
            CookieStore store = ((CookieManager) CookieHandler.getDefault()).getCookieStore();
            try {
                Files.write(Values.COOKIESFILE.toPath(), ("").getBytes(), StandardOpenOption.TRUNCATE_EXISTING);

                for (URI uri : store.getURIs()) {
                    Map<String, List<String>> map = CookieHandler.getDefault().get(uri, new HashMap<>());

                    Files.write(Values.COOKIESFILE.toPath(), (uri + "|").getBytes(), StandardOpenOption.APPEND);

                    for (String value : map.keySet()) {
                        Files.write(Values.COOKIESFILE.toPath(), (value + ":").getBytes(), StandardOpenOption.APPEND);

                        for (String line : map.get(value))
                            Files.write(Values.COOKIESFILE.toPath(), (line + ";").getBytes(), StandardOpenOption.APPEND);

                        Files.write(Values.COOKIESFILE.toPath(), ("\n").getBytes(), StandardOpenOption.APPEND);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });

    addTab();
}

@Override
public void start(Stage primaryStage) {
    this.stage = primaryStage;
    stage.setTitle("Browser");

    try {
        // Load person overview.
        FXMLLoader loader = new FXMLLoader();
        loader.setController(this);
        loader.setLocation(Main.class.getResource("/browser.fxml"));
        pane = loader.load();

        Scene scene = new Scene(pane);
        stage.setScene(scene);
        stage.show();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void setURL(String url) {
    tabs.get(tabPane.getSelectionModel().getSelectedIndex()).setURL(url);
}

public void search(String text) {
    tabs.get(tabPane.getSelectionModel().getSelectedIndex()).search(text);
}

void addTab() {
    BrowserTab browserTab = new BrowserTab(this);
    browserTab.setText("Loading...");
    browserTab.setURL("https://google.com/");

    tabs.add(browserTab);

    browserTab.setOnClosed(new EventHandler<Event>() {
        @Override
        public void handle(Event event) {
            tabs.remove(browserTab);

            if (tabPane.getTabs().isEmpty())
                Platform.exit();
        }
    });
    tabPane.getTabs().add(browserTab);
}

我的BrowserTab类

public class BrowserTab extends Tab {

private Main main;

private GridPane pane;

@FXML
private WebView webView;
@FXML
private TextField urlField;
@FXML
private Button backButton;
@FXML
private Button forwardButton;
@FXML
private Button goButton;
@FXML
private Button addTabButton;

public BrowserTab(Main main) {
    this.main = main;

    try {
        FXMLLoader loader = new FXMLLoader();
        loader.setController(this);
        loader.setLocation(getClass().getResource("/tab-template.fxml"));

        setContent(loader.load());
    } catch (IOException e) {
        e.printStackTrace();
    }

    initialize();
}

@FXML
public void initialize() {
    webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
        @Override
        public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
            if (newState == Worker.State.SUCCEEDED) {
                String title = webView.getEngine().titleProperty().getValue();

                if (title == null || title.trim().isEmpty())
                    title = webView.getEngine().getLocation();

                setText(title);
                urlField.setText(webView.getEngine().getLocation());
            }
        }
    });

    backButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WebHistory history = webView.getEngine().getHistory();

            history.go(-1);

            int index = history.getCurrentIndex();

            if (index + 1 > history.getEntries().size() - 1)
                forwardButton.setDisable(true);
            else
                forwardButton.setDisable(false);

            if (index - 1 < 0)
                backButton.setDisable(true);
            else
                backButton.setDisable(false);
        }
    });

    forwardButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            WebHistory history = webView.getEngine().getHistory();

            history.go(1);

            int index = history.getCurrentIndex();

            if (index + 1 > history.getEntries().size() - 1)
                forwardButton.setDisable(true);
            else
                forwardButton.setDisable(false);

            if (index - 1 < 0)
                backButton.setDisable(true);
            else
                backButton.setDisable(false);
        }
    });

    urlField.setOnKeyPressed(new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent event) {
            if (event.getCode() == KeyCode.ENTER)
                goButton.fire();
        }
    });

    goButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            String url = urlField.getText();

            if (!url.contains(".")) {
                search(url);
                return;
            }

            if (!(url.startsWith("http://") || url.startsWith("https://")))
                url = "http://" + url;

            setURL(url);
        }
    });

    webView.getEngine().getHistory().getEntries().addListener(new ListChangeListener<WebHistory.Entry>() {
        @Override
        public void onChanged(Change<? extends WebHistory.Entry> c) {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    int index = webView.getEngine().getHistory().getCurrentIndex();

                    System.out.println(index);

                    if (index + 1 > c.getList().size() - 1)
                        forwardButton.setDisable(true);
                    else
                        forwardButton.setDisable(false);

                    if (index - 1 < 0)
                        backButton.setDisable(true);
                    else
                        backButton.setDisable(false);
                }
            });
        }
    });

    addTabButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            addTab();
        }
    });
}

public void setURL(String url) {
    webView.getEngine().load(url);
}

public void search(String text) {
    webView.getEngine().load("https://google.com/search?q=" + text);
}

private void addTab() {
    main.addTab();
}

文件格式如下:

uri1|value:string1;string2;string3;
uri2|value:string1;string2;string3;

真的很感激任何帮助。

1 个答案:

答案 0 :(得分:2)

在经过一些挖掘之后,我找到了解决方案。 问题是地图内的默认字符串(关键元素)始终是&#39; Cookie:&#39;。但是,在创建地图以将其实际添加到CookieHandler时,它应该是“Set-Cookie&#39;或者&#39; Set-Cookie2&#39;。如果它不是其中之一,那么它只是跳过该值而您最终根本没有cookie。此外,我最终使用CookieManager和一些方法将cookie转换为字符串,反之亦然。在创建CookieManager时,您必须小心选择具有两个参数(cookiestore和cookiepolicy)的构造函数,而不是具有零参数的构造函数。选择零参数的那个将不会创建cookiestore并导致错误。当使用具有两个参数的那个时,只需将商店保留为空,它将为您创建一个。这就是我最终使用的内容:

保存:

CookieStore store = ((CookieManager) CookieHandler.getDefault()).getCookieStore();
try {
  Files.write(Values.COOKIESFILE.toPath(), ("").getBytes(), StandardOpenOption.TRUNCATE_EXISTING);

  for (URI uri : store.getURIs()) {
    Map<String, List<String>> map = CookieHandler.getDefault().get(uri, new HashMap<>());

    Files.write(Values.COOKIESFILE.toPath(), (uri + "|Cookie:").getBytes(), StandardOpenOption.APPEND);

    for (HttpCookie cookie : store.get(uri)) {
      if (cookie.hasExpired())
        continue;

      Files.write(Values.COOKIESFILE.toPath(), (CookieUtil.toString(cookie) + "~").getBytes(), StandardOpenOption.APPEND);
    }

    Files.write(Values.COOKIESFILE.toPath(), "\n".getBytes(), StandardOpenOption.APPEND);
  }
} catch (IOException e) {
  e.printStackTrace();
}

装载:

CookieManager manager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);

try {
  for (String line : Files.readAllLines(Values.COOKIESFILE.toPath())) {
    String[] values = line.split("\\|");
    URI uri = new URI(values[0]);

    String[] actualValues = values[1].split(":");

    if (actualValues.length < 2)
      continue;

    for (String header : actualValues[1].split("~"))
      manager.getCookieStore().add(uri, CookieUtil.fromString(header));
    }
  } catch (IOException | URISyntaxException e) {
    e.printStackTrace();
  }

CookieHandler.setDefault(manager);