我目前正在尝试使用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;
真的很感激任何帮助。
答案 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);