web-dev-qa-db-ja.com

JavaFXのWebEngine / WebViewを使用してCookieを設定する

JavaFXで WebEngine / WebView を使用してプログラムでcookieを設定する方法を見つけることができないようです。 APIは、ヘッダーを変更するためにHttpRequestのようなオブジェクトを取得する方法(XML-RPCのアプリで使用するもの)や、あらゆる種類のCookieマネージャーについては何も考えていません。

このページの質問は問題に触れていないようです- this がありますが、 bug を修正するためにアプレットでCookieを無効にするだけで、私のアプリはデスクトップにあります。

私がイメージできる唯一の方法は、最初のページ(セッションIDを含むCookieが適切に読み込まれる必要があります)を要求し、「アクセス拒否」スタイルのメッセージを取得し、Cookieを設定するページコンテキストでJavaScriptを実行することです。その後、リフレッシュ。この解決策は、恐ろしいユーザーエクスペリエンスになります。

WebEngineを使用してCookieを設定するにはどうすればよいですか?


更新:上記のリンクされた質問からヒントを得て、 CookieManager と関連するAPIの使用例を探してみました。 このコードを見つけました 、これをアプリに組み込んでみましたが、奇妙な結果になりました。

MyCookieStore cookie_store = new MyCookieStore();
CookieManager cookie_manager = new CookieManager(cookie_store, new MyCookiePolicy());
CookieHandler.setDefault(cookie_manager);
WebView wv = new WebView();

これを行うとしましょう:

String url = "http://www.google.com/";
wv.getEngine.go(url);

このリクエストが行われた後のEclipseでのデバッグは、CookieストアマップがCookieを保持していることを示しています。

{http://www.google.com/=[NID=67=XWOQNK5VeRGEIEovNQhKsQZ5-laDaFXkzHci_uEI_UrFFkq_1d6kC-4Xg7SLSB8ZZVDjTUqJC_ot8vaVfX4ZllJ2SHEYaPnXmbq8NZVotgoQ372eU8NCIa_7X7uGl8GS, PREF=ID=6505d5000db18c8c:FF=0:TM=1358526181:LM=1358526181:S=Nzb5yzBzXiKPLk48]}

それはIS AWESOME

WebEngineは、基になる登録済みCookieエンジンを使用するだけです!しかし、待って、それは本当にですか?リクエストを行う前に、クッキーを追加してみましょう...

cookie_store.add(new URL(url).toURI(), new HttpCookie("testCookieKey", "testCookieValue"));

次に、Wiresharkでリクエストを確認します...

GET / HTTP/1.1
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/535.14 (KHTML, like Gecko) JavaFX/2.2 Safari/535.14
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cache-Control: no-cache
Pragma: no-cache
Host: www.google.com
Connection: keep-alive

私にはクッキーはありません:(

何が悪いのですか?

42
Dreen

私はこの問題をOracleのVasiliy Baranovの助けを借りて解決することができました。 Vasiliyが私に書いた:

WebViewが初めてインスタンス化された後、_WebEngine.load_が呼び出される前に、CookieをJava.net.CookieHandler.getDefault()に入れてみてください。次のように:

_WebView webView = new WebView();
URI uri = URI.create("http://mysite.com");
Map<String, List<String>> headers = new LinkedHashMap<String, List<String>>();
headers.put("Set-Cookie", Arrays.asList("name=value"));
Java.net.CookieHandler.getDefault().put(uri, headers);
webView.getEngine().load("http://mysite.com");
_

これにより、Cookieがストアに永続的に配置され、後続のすべてのリクエストで送信されるはずです(おそらくサーバーが設定を解除しない限り)。

Vasiliyはまた、WebViewCookieHandlerの独自の実装をインストールし、デフォルトのCookieはそのままにしておくと説明しました。

最後に、彼は非常に興味をそそるものに言及します:

_Java.net.CookieManager_および_Java.net.CookieStore_の使用に時間を費やさないでください。間違った標準を実装しているため、多くのサイトで問題を引き起こす可能性があります。

このあとググってみましたが常識ではないようです。誰かがより詳細な情報を提供することができれば私は感謝します。 CookieStoreCookieManagerは多くのソフトウェアで使用されているため、奇妙に思われます。

45
Dreen

Java.net.CookieManagerのソリューション

Cookieのシリアル化:

        List<HttpCookie> httpCookies = cookieManager.getCookieStore().getCookies();
        Gson gson = new GsonBuilder().create();
        String jsonCookie = gson.toJson(httpCookies);

Cookieの逆シリアル化:

Gson gson = new GsonBuilder().create();
List<HttpCookie> httpCookies = new ArrayList<>();
Type type = new TypeToken<List<HttpCookie>>() {}.getType();
httpCookies = gson.fromJson(json, type);   // convert json string to list
for (HttpCookie cookie : httpCookies) {
    cookieManager.getCookieStore().add(URI.create(cookie.getDomain()), cookie);
}
2
Vladimir