JavaFX webview 不保存 cookie

标签 java javafx webview

我对 JavaFX 很陌生,需要使用浏览器窗口编写应用程序。该浏览器将用于登录 microstock Agency fotolia,以解决登录时出现的验证码。显然,在关闭并稍后重新启动我的应用程序时,cookie 没有保存。

有没有办法在 JavaFX/webview 中存储下一个 session 的 cookie?或者谁能​​告诉我,为什么不存储cookie?

最佳答案

JavaFX webview 使用内存中的 cookie 存储,因此不会在 session 之间保留 cookie。
您需要自己实现一个 cookie 存储。

public class myCookieStore implements CookieStore {...this is where you implement the interface...}
然后,在该存储中,您维护 cookie 列表。
可能是这样,但这取决于你。
 private List<HttpCookie> cookies = new ArrayList<>();
一旦你这样做了,在你的 javaFX 初始化函数中,你将 webEngine cookiestore 设置为你的实现。
 @Override
public void initialize(URL location, ResourceBundle resources) {
    WebEngine engine = this.webViewID.getEngine();
    java.net.CookieManager manager = new CookieManager(new myCookieStore(),CookiePolicy.ACCEPT_ALL);
    java.net.CookieHandler.setDefault(manager);}
在 CookieStore 的实现中,您必须将该 cookie 列表保存到文件(或数据库,或您放置它的任何位置),然后在您的应用程序重新加载时重新加载它。
这是我个人遇到障碍的地方,也是我如何找到你的问题的地方。 HttpCookie 没有实现可序列化并且具有不会反射(reflect)的私有(private)字段 - 这意味着您不能简单地序列化和反序列化列表,并且使用 gson.toJson() (此处列出的解决方案 Setting a cookie using JavaFX's WebEngine/WebView )也会失败。您可能必须手动保存 cookie 字段并重建 cookie。如果我真的让它自己工作,我会用一个解决方案来更新它。
///更新///
事实证明,HTTPCookie 的序列化问题始于 Java 9。如果您使用 Java 8,那么您可以简单地实现 cookiestore 接口(interface),然后使用之前链接帖子中的 Gson 示例来持久化该列表。但是,如果您使用的是 Java 9 或更高版本,则不能再执行此操作,因为它会阻止 gson 用于访问私有(private)字段的反射。
我重新实现了 HTTPCookie 对象的可公开访问的成员,如下所示:
 public class myCookieClass implements Serializable{
    private URI uri;
    private String name;
    private String value;
    private String domain;
    private String path;
    private String portList;
    private String comment;
    private String commentURL;
    private boolean httpOnly;
    private boolean discard;
    private long maxAge;
    private boolean secure;
    private int version;



    public myCookieClass(URI uri, HttpCookie cookie){
        name = cookie.getName();
        value = cookie.getValue();
        domain = cookie.getDomain();
        maxAge =cookie.getMaxAge();
        path = cookie.getPath();
        httpOnly = cookie.isHttpOnly();
        portList = cookie.getPortlist();
        discard = cookie.getDiscard();
        secure = cookie.getSecure();
        version = cookie.getVersion();
        comment = cookie.getComment();
        commentURL = cookie.getCommentURL();
        this.uri = uri;
    }

    public HttpCookie toCookie(){
        HttpCookie cookie =  new HttpCookie(this.name,this.value);
        cookie.setSecure(secure);
        cookie.setDomain(domain);
        cookie.setMaxAge(maxAge);
        cookie.setPath(path);
        cookie.setHttpOnly(httpOnly);
        cookie.setPortlist(portList);
        cookie.setDiscard(discard);
        cookie.setVersion(version);
        cookie.setComment(comment);
        cookie.setCommentURL(commentURL);
        cookie.setValue(value);
        return cookie;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        myCookieClass that = (myCookieClass) o;
        return  uri.equals(that.uri) &&
                name.equals(that.name);

    }

    @Override
    public int hashCode() {
        return Objects.hash(uri, name);
    }
}
然后,我使用与以前基本相同的 gson 示例来保存和恢复该列表。
   public void RestoreCookieStoreFromFile(){
    try {
        File file = new File(fileName);
        if (file.exists()) {
            System.out.println("RESTORE COOKIES");
            FileReader fileReader = new FileReader(fileName);
            String json = new String(Files.readAllBytes(Paths.get(fileName)));
            Gson gson = new GsonBuilder().create();
            Type type = new TypeToken<List<myCookieClass>>() {
            }.getType();
            cookies = gson.fromJson(json, type);

        }
        } catch(FileNotFoundException e){
            //file not found
            e.printStackTrace();
        } catch(IOException e){
            // cant create object stream
            e.printStackTrace();
        }


}

private void saveCookieStoreToFile(String location){
    try {
        Gson gson = new GsonBuilder().create();
        String jsonCookie = gson.toJson(cookies);
        Files.writeString(Path.of(fileName),jsonCookie);

    } catch (FileNotFoundException e) {
        // file not found
        System.out.println("Can't Save File");
        e.printStackTrace();
    } catch (IOException e) {
        System.out.println("Can't Save File OUTSTREAM");
        // can't create output stream
        e.printStackTrace();
    }
    catch (InaccessibleObjectException e){
        System.out.println("Can't Access object");
        e.printStackTrace();
    }
}
这些是实际工作的 cookiestore 接口(interface)成员,至少在我的情况下是这样。还有一些成员,但似乎没有人称这些成员。
  @Override
public void add(URI uri, HttpCookie cookie)
{

        cookies.add(new myCookieClass(uri,cookie));

        saveCookieStoreToFile(fileName);

}


@Override
public List<HttpCookie> get(URI uri) {


    List<HttpCookie> uriCookies = new ArrayList<>();
    myCookieClass[] tempCookies = cookies.toArray(myCookieClass[]::new);
    for (myCookieClass c: tempCookies) {
        if(c.uri.toString().contains(uri.getRawAuthority())){
            uriCookies.add(c.toCookie());
        }
    }
        return uriCookies;
}


@Override
public List<HttpCookie> getCookies() {

        List<HttpCookie> httpCookies = new ArrayList<>();
        myCookieClass[] tempCookies = cookies.toArray(myCookieClass[]::new);
        for (myCookieClass c : tempCookies) {
            httpCookies.add(c.toCookie());
        }

        return httpCookies;

}
为了完整起见,这是将我的 cookie 保存在内存中的列表。
 private List<myCookieClass> cookies = new ArrayList<>();
一如既往,祝你好运!

关于JavaFX webview 不保存 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48251340/

相关文章:

java - GWT/文本框-单击和双击处理程序选项?可能的?

java - 让复选框记住其状态的最佳方法是什么?

java - 使用 javafx 创建自定义树

swift - WKWebView无法拖动Element

android - 在Webview中长按-应用崩溃

java - 登录时 Smack 4.2.0 NullPointerException

java - 使用 hibernate OGM 为 mongoDB 启用 SSL

java - JavaFX 的 TextField 的值更改监听器

ios - 如何改变WebVIew iPhone的文字颜色

java - 双向链表对象错误