web-dev-qa-db-fra.com

Configuration d'un cookie à l'aide de WebEngine/WebView de JavaFX

Je n'arrive pas à trouver le moyen de définir un cookie par programme en utilisant WebEngine / WebView en JavaFX. L'API ne donne aucune idée de la façon d'obtenir un objet de type HttpRequest pour modifier les en-têtes (ce que j'utilise dans l'application pour XML-RPC), ni aucun type de gestionnaire de cookies.

Aucune question sur cette page ne semble toucher au problème non plus - il y a this mais cela désactive simplement les cookies lorsque vous êtes dans une applet pour corriger un bug , mon application est sur le bureau.

Je ne peux le faire que si je demande la première page (ce qui nécessite un cookie avec un ID de session pour se charger correctement), en obtenant un message de type "accès refusé", en exécutant du javascript dans le contexte de la page qui définit le cookie et puis rafraîchissant. Cette solution serait une expérience utilisateur horrible cependant.

Comment définir un cookie à l'aide de WebEngine?


Mise à jour: Prenant un indice d'une question liée ci-dessus, j'ai essayé de chercher des exemples d'utilisation de CookieManager et des API associées. J'ai trouvé ce code , que j'ai ensuite essayé d'intégrer à mon application, avec des résultats étranges;

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

Maintenant, disons que nous faisons ceci:

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

Le débogage dans Eclipse après que cette demande a été faite montre que la carte de la banque de cookies contient un 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]}

QUE IS IMPRESSIONNANT

WebEngine utilise simplement le moteur de cookie enregistré sous-jacent! Mais attendez, est-ce vraiment? Essayons d'ajouter un cookie avant de faire la demande ...

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

Ensuite, je regarde la demande dans 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

Pas de cookie pour moi :(

Qu'est-ce que je fais mal?

42
Dreen

J'ai réussi à résoudre ce problème avec l'aide de Vasiliy Baranov d'Oracle. Vasiliy m'a écrit:

Essayez de placer le cookie dans Java.net.CookieHandler.getDefault() après la WebView est instanciée pour la première fois et avant l'appel de WebEngine.load, par exemple comme suit:

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

Cela place le cookie dans le magasin de façon permanente. Il doit être envoyé à chaque nouvelle demande (probablement à condition que le serveur ne le désactive pas).

Vasiliy a également expliqué que WebView installera sa propre implémentation de CookieHandler, tout en conservant les cookies placés dans celle par défaut.

Enfin, il mentionne quelque chose d'assez intriguant:

Ne perdez pas votre temps à essayer d'utiliser Java.net.CookieManager et Java.net.CookieStore. Ils sont susceptibles de causer des problèmes avec beaucoup sites parce qu'ils implémentent la mauvaise norme.

J'ai essayé de googler après cela, mais cela ne semble pas être une connaissance commune. Si quelqu'un est en mesure de fournir plus de détails, je vous en serais reconnaissant. Cela semble bizarre, puisqu'il semble que CookieStore et CookieManager soient utilisés par de nombreux logiciels.

45
Dreen

Solution pour Java.net.CookieManager

Sérialisation des cookies:

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

Désérialisation des cookies:

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