Передача файлов cookie из HttpURLConnection (java.net.CookieManager) в WebView (android.webkit.CookieManager)

Я видел ответы о том, как это должно работать со старым DefaultHttpClient но нет хорошего примера для HttpURLConnection

Я использую HttpURLConnection для запросов в веб-приложение. В начале моего приложения для Android я использую CookieHandler.setDefault(new CookieManager()) чтобы автоматически обрабатывать cookies сеансов, и это работает нормально.

В какой-то момент после входа в систему я хочу показать живые страницы из веб-приложения пользователю с помощью WebView вместо загрузки данных за кулисами с помощью HttpURLConnection . Тем не менее, я хочу использовать тот же самый сеанс, который я установил ранее, чтобы пользователь не мог снова войти в систему.

Как скопировать cookies из java.net.CookieManager используемого HttpURLConnection в android.webkit.CookieManager используемый WebView чтобы я мог поделиться сеансом?

4 Solutions collect form web for “Передача файлов cookie из HttpURLConnection (java.net.CookieManager) в WebView (android.webkit.CookieManager)”

Я хотел бы предложить совершенно другой подход к вашей проблеме. Вместо того, чтобы копировать cookies из одного места в другое (ручная синхронизация), давайте сделаем HttpURLConnection и WebViews одним и тем же хранилищем файлов cookie.

Это полностью исключает необходимость синхронизации. Любой cookie, обновленный в любом из них, будет немедленно и автоматически отражен в другом.

Для этого создайте свою собственную реализацию java.net.CookieManager, которая перенаправляет все запросы в webkit WebViews android.webkit.CookieManager.

Реализация:

 import java.io.IOException; import java.net.CookieManager; import java.net.CookiePolicy; import java.net.CookieStore; import java.net.URI; import java.util.Arrays; import java.util.List; import java.util.Map; public class WebkitCookieManagerProxy extends CookieManager { private android.webkit.CookieManager webkitCookieManager; public WebkitCookieManagerProxy() { this(null, null); } WebkitCookieManagerProxy(CookieStore store, CookiePolicy cookiePolicy) { super(null, cookiePolicy); this.webkitCookieManager = android.webkit.CookieManager.getInstance(); } @Override public void put(URI uri, Map> responseHeaders) throws IOException { // make sure our args are valid if ((uri == null) || (responseHeaders == null)) return; // save our url once String url = uri.toString(); // go over the headers for (String headerKey : responseHeaders.keySet()) { // ignore headers which aren't cookie related if ((headerKey == null) || !(headerKey.equalsIgnoreCase("Set-Cookie2") || headerKey.equalsIgnoreCase("Set-Cookie"))) continue; // process each of the headers for (String headerValue : responseHeaders.get(headerKey)) { this.webkitCookieManager.setCookie(url, headerValue); } } } @Override public Map> get(URI uri, Map> requestHeaders) throws IOException { // make sure our args are valid if ((uri == null) || (requestHeaders == null)) throw new IllegalArgumentException("Argument is null"); // save our url once String url = uri.toString(); // prepare our response Map> res = new java.util.HashMap>(); // get the cookie String cookie = this.webkitCookieManager.getCookie(url); // return it if (cookie != null) res.put("Cookie", Arrays.asList(cookie)); return res; } @Override public CookieStore getCookieStore() { // we don't want anyone to work with this cookie store directly throw new UnsupportedOperationException(); } } 

и, наконец, использовать его, выполнив это при инициализации вашего приложения:

 android.webkit.CookieSyncManager.createInstance(appContext); // unrelated, just make sure cookies are generally allowed android.webkit.CookieManager.getInstance().setAcceptCookie(true); // magic starts here WebkitCookieManagerProxy coreCookieManager = new WebkitCookieManagerProxy(null, java.net.CookiePolicy.ACCEPT_ALL); java.net.CookieHandler.setDefault(coreCookieManager); 

По сравнению с DefaultHttpClient , есть несколько дополнительных шагов. Ключевое различие заключается в том, как получить доступ к существующим файлам cookie в HTTPURLConnection :

  1. Вызовите CookieHandler.getDefault() и CookieHandler.getDefault() результат в java.net.CookieManager .
  2. С менеджером getCookieStore() cookie вызовите getCookieStore() для доступа к хранилищу getCookieStore() cookie.
  3. В хранилище файлов cookie вызовите get() чтобы получить доступ к списку файлов cookie для данного URI .

Вот полный пример:

 @Override protected void onCreate(Bundle savedInstanceState) { // Get cookie manager for WebView // This must occur before setContentView() instantiates your WebView android.webkit.CookieSyncManager webCookieSync = CookieSyncManager.createInstance(this); android.webkit.CookieManager webCookieManager = CookieManager.getInstance(); webCookieManager.setAcceptCookie(true); // Get cookie manager for HttpURLConnection java.net.CookieStore rawCookieStore = ((java.net.CookieManager) CookieHandler.getDefault()).getCookieStore(); // Construct URI java.net.URI baseUri = null; try { baseUri = new URI("http://www.example.com"); } catch (URISyntaxException e) { // Handle invalid URI ... } // Copy cookies from HttpURLConnection to WebView List cookies = rawCookieStore.get(baseUri); String url = baseUri.toString(); for (HttpCookie cookie : cookies) { String setCookie = new StringBuilder(cookie.toString()) .append("; domain=").append(cookie.getDomain()) .append("; path=").append(cookie.getPath()) .toString(); webCookieManager.setCookie(url, setCookie); } // Continue with onCreate ... } 

Я волшебно решил все проблемы с файлами cookie с этой одной строкой в ​​onCreate:

CookieHandler.setDefault(new CookieManager());

У меня была та же проблема, и это мое решение:

Сразу после входа в систему (это важно, потому что раньше у вас может быть еще не cookie), используя httpurlconnection POST (после getResponseCode), я делаю:

  responseCode = connexion.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { final String COOKIES_HEADER = "Set-Cookie"; cookie = connexion.getHeaderField(COOKIES_HEADER); ... } 

(где cookie – это публичная строка в моем classе)

И в активности веб-просмотра, где я хочу отображать веб-страницу с сервера с помощью WebView, я делаю:

  String url = "http://toto.com/titi.html"; // the url of the page you want to display CookieSyncManager.createInstance(getActivity()); CookieSyncManager.getInstance().startSync(); android.webkit.CookieManager cookieManager = android.webkit.CookieManager.getInstance(); cookieManager.setAcceptCookie(true); cookieManager.removeSessionCookie(); cookieManager.setCookie(url, cookie); CookieSyncManager.getInstance().sync(); 

Поскольку мой веб-просмотр во fragmentе, мне пришлось использовать getActivity () для контекста, мне также пришлось указать android.webkit. перед CookieManager иначе он не может быть разрешен (импортируйте java.net вместо менеджера android.webkit cookie).

cookie – это тот же String, что и выше (в моем fragmentе мне пришлось восстановить его, используя:

  cookie = getArguments().getString(COOKIE); 

и в моей MainActivity, я отправляю его:

  Bundle arg = new Bundle(); arg.putString(Fragment_Cameras.COOKIE, cookie); fragment.setArguments(arg); 

Я надеюсь, это поможет!

Interesting Posts

Где найти номер строки в редакторе Xcode?

Я не могу ввести текст в поле «Поиск программ и файлов» в меню «Пуск»

Как сделать тип привязки данных безопасным и поддерживать рефакторинг

Изменение раскладки клавиатуры win7 с экрана входа в систему

Случайно dd'ed изображение к неправильному диску / переписал таблицу разделов + начало раздела NTFS

Обманите приложение, думая, что его выступление – это терминал, а не труба

Панель не получает фокус

Вызов функции startActivity () извне активности?

Угловая директива динамического шаблона Angular.js

Настройте точку вместо запятой в числовых значениях

Как добавить элементы в общую коллекцию подстановочных знаков?

Должны ли получатели Java 8 возвращать дополнительный тип?

Асинхронный доступ к массиву в Firebase

Почему шаблон функции не может быть частично специализированным?

Создайте пользователя Windows XP из раздела Linux

Давайте будем гением компьютера.