Установка файла cookie с использованием JavaFX WebEngine/WebView

Я не могу найти какой-либо способ установить cookie программно с помощью WebEngine / WebView в JavaFX. API не дает никакого представления о том, как получить HttpRequest-подобный объект для изменения заголовков (что я и использую в приложении для XML-RPC) или какой-либо менеджер файлов cookie.

Никакие вопросы на этой странице, кажется, также не касаются этой проблемы - она ​​есть, но она просто отключает куки, когда в апплете исправляется ошибка, и мое приложение находится на рабочем столе, кстати.

Единственный способ, которым я могу представить это, - это запрос первой страницы (для корректной загрузки которой требуется файл cookie с sessionID), получение сообщения в стиле "отказано в доступе", выполнение некоторого javascript в контексте страницы, который устанавливает cookie и потом освежаю. Это решение было бы ужасным для пользователя.

Как мне установить cookie с помощью WebEngine?


Обновление: Поняв вопрос из вышеупомянутого вопроса, я попытался найти примеры использования 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]}

ЭТО ЗАМЕЧАТЕЛЬНО

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

Нет печенья для меня:(

Что я делаю неправильно?

2 ответа

Решение

Мне удалось решить эту проблему с помощью Василия Баранова из Oracle. Василий написал мне:

Попробуйте положить печенье в java.net.CookieHandler.getDefault() после первого создания WebView и перед вызовом WebEngine.loadНапример, следующим образом:

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 в хранилище на постоянной основе, его следует отправлять при каждом последующем запросе (предположительно, при условии, что сервер не отменяет его).

Василий также объяснил, что WebView установит свою собственную реализацию CookieHandlerпри сохранении куки-файлов положить в файл по умолчанию.

Наконец, он упоминает нечто весьма интригующее:

Не тратьте свое время на попытки использования java.net.CookieManager, а также java.net.CookieStore, Они могут вызвать проблемы со многими сайтами, потому что они реализуют неправильный стандарт.

После этого я попробовал поискать в Google, но это, похоже, не является общеизвестным. Если кто-то может предоставить более подробную информацию, я был бы признателен. Кажется странным, так как кажется CookieStore а также CookieManager используются большим количеством программного обеспечения там.

Решение для 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);
}
Другие вопросы по тегам