Impostazione di un cookie utilizzando WebEngine / WebView di JavaFX

Non riesco a trovare alcun modo per impostare un cookie in modo programmatico utilizzando WebEngine / WebView in JavaFX. L’API non fornisce alcuna idea su come ottenere un object HttpRequest per modificare le intestazioni (che è quello che uso nell’app per XML-RPC), o qualsiasi tipo di cookie manager.

Neanche le domande su questa pagina sembrano toccare il problema – c’è ma disabilita i cookie quando nell’applet si risolve un bug , la mia app è sul desktop btw.

L’unico modo in cui l’immagine che potrei fare è richiedendo la prima pagina (che richiede un cookie con un sessionID da caricare correttamente), ottenendo un messaggio di “accesso negato”, eseguendo qualche javascript nel contesto della pagina che imposta il cookie e quindi rinfrescante. Questa soluzione sarebbe però un’esperienza utente orribile.

Come posso impostare un cookie usando WebEngine?


Aggiornamento: Prendendo spunto da una domanda collegata in precedenza, ho provato a scavare per alcuni esempi di utilizzo di CookieManager e API correlate. Ho trovato questo codice , che ho poi provato ad incorporare nella mia app, con risultati strani;

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

Ora diciamo di farlo:

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

Il debugging in Eclipse dopo che è stata effettuata questa richiesta mostra che la mappa dell’archivio dei cookie contiene 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]} 

QUESTO È IMPRESSIONANTE

WebEngine utilizza semplicemente il motore cookie registrato sottostante! Ma aspetta, è davvero? Proviamo ad aggiungere un cookie, prima di fare la richiesta …

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

Poi guardo la richiesta in 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 

Nessun cookie per me 🙁

Che cosa sto facendo di sbagliato?

Sono riuscito a risolvere questo problema con l’aiuto di Vasiliy Baranov di Oracle. Vasiliy mi ha scritto:

Prova a mettere il cookie in java.net.CookieHandler.getDefault() dopo che WebView è stato istanziato per la prima volta e prima della chiamata a WebEngine.load , ad es. Come segue:

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

Questo inserirà il cookie nel negozio in modo permanente, dovrebbe essere inviato ad ogni richiesta successiva (presumibilmente a condizione che il server non lo disattivi).

Vasiliy ha anche spiegato che WebView installerà la propria implementazione di CookieHandler , pur mantenendo i cookie inseriti in quello predefinito.

Infine, menziona qualcosa di piuttosto intrigante:

Non perdere tempo a cercare di utilizzare java.net.CookieManager e java.net.CookieStore . È probabile che causino problemi con molti siti perché implementano lo standard sbagliato.

Ho provato googling dopo questo, ma non sembra essere conoscenza comune. Se qualcuno è in grado di fornire maggiori dettagli sarei grato. Sembra strano, dal momento che sembra che CookieStore e CookieManager siano utilizzati da molti software in CookieManager .

Soluzione per java.net.CookieManager

Serializzazione dei cookie:

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

Deserializzazione dei cookie:

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