Как сделать HTTP-запрос с помощью файлов cookie на Android?

Я хотел бы сделать http-запрос на удаленный сервер, правильно обрабатывая cookies (например, хранить cookies, отправленные сервером, и отправлять эти куки, когда я делаю последующие запросы). Было бы неплохо сохранить все и все cookies, но на самом деле единственное, что мне волнует, – это cookie сеанса.

С java.net кажется, что предпочтительный способ сделать это – использовать java.net.CookieHandler (абстрактный базовый class) и java.net.CookieManager (конкретная реализация). Android имеет java.net.CookieHandler, но у него, похоже, нет java.net.CookieManager.

Я могу закодировать все это вручную, проверяя заголовки http, но похоже, что должен быть более простой способ.

Каким образом можно создавать HTTP-запросы на Android при сохранении файлов cookie?

Оказывается, Google Android поставляется с Apache HttpClient 4.0, и я смог выяснить, как это сделать, используя пример входа на основе формы в документах HttpClient :

http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/apache/http/examples/client/ClientFormLogin.java


 import java.util.ArrayList; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; /** * A example that demonstrates how HttpClient APIs can be used to perform * form-based logon. */ public class ClientFormLogin { public static void main(String[] args) throws Exception { DefaultHttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet("https://portal.sun.com/portal/dt"); HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); System.out.println("Login form get: " + response.getStatusLine()); if (entity != null) { entity.consumeContent(); } System.out.println("Initial set of cookies:"); List cookies = httpclient.getCookieStore().getCookies(); if (cookies.isEmpty()) { System.out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { System.out.println("- " + cookies.get(i).toString()); } } HttpPost httpost = new HttpPost("https://portal.sun.com/amserver/UI/Login?" + "org=self_registered_users&" + "goto=/portal/dt&" + "gotoOnFail=/portal/dt?error=true"); List  nvps = new ArrayList (); nvps.add(new BasicNameValuePair("IDToken1", "username")); nvps.add(new BasicNameValuePair("IDToken2", "password")); httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); response = httpclient.execute(httpost); entity = response.getEntity(); System.out.println("Login form get: " + response.getStatusLine()); if (entity != null) { entity.consumeContent(); } System.out.println("Post logon cookies:"); cookies = httpclient.getCookieStore().getCookies(); if (cookies.isEmpty()) { System.out.println("None"); } else { for (int i = 0; i < cookies.size(); i++) { System.out.println("- " + cookies.get(i).toString()); } } // When HttpClient instance is no longer needed, // shut down the connection manager to ensure // immediate deallocation of all system resources httpclient.getConnectionManager().shutdown(); } } 

Файл cookie – это еще один HTTP-заголовок. Вы всегда можете установить его при вызове HTTP с помощью библиотеки apache или с помощью HTTPUrlConnection. В любом случае вы должны иметь возможность читать и устанавливать HTTP-cookies таким образом.

Вы можете прочитать эту статью для получения дополнительной информации.

Я могу поделиться своим миром кода, чтобы продемонстрировать, насколько легко вы можете это сделать.

 public static String getServerResponseByHttpGet(String url, String token) { try { HttpClient client = new DefaultHttpClient(); HttpGet get = new HttpGet(url); get.setHeader("Cookie", "PHPSESSID=" + token + ";"); Log.d(TAG, "Try to open => " + url); HttpResponse httpResponse = client.execute(get); int connectionStatusCode = httpResponse.getStatusLine().getStatusCode(); Log.d(TAG, "Connection code: " + connectionStatusCode + " for request: " + url); HttpEntity entity = httpResponse.getEntity(); String serverResponse = EntityUtils.toString(entity); Log.d(TAG, "Server response for request " + url + " => " + serverResponse); if(!isStatusOk(connectionStatusCode)) return null; return serverResponse; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return null; } 

Поскольку библиотека Apache устарела , для тех, кто хочет использовать HttpURLConncetion , я написал этот class, чтобы отправить Get и Post Request с помощью этого ответа :

 public class WebService { static final String COOKIES_HEADER = "Set-Cookie"; static final String COOKIE = "Cookie"; static CookieManager msCookieManager = new CookieManager(); private static int responseCode; public static String sendPost(String requestURL, String urlParameters) { URL url; String response = ""; try { url = new URL(requestURL); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(15000); conn.setConnectTimeout(15000); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json; charset=utf-8"); if (msCookieManager.getCookieStore().getCookies().size() > 0) { //While joining the Cookies, use ',' or ';' as needed. Most of the server are using ';' conn.setRequestProperty(COOKIE , TextUtils.join(";", msCookieManager.getCookieStore().getCookies())); } conn.setDoInput(true); conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os, "UTF-8")); if (urlParameters != null) { writer.write(urlParameters); } writer.flush(); writer.close(); os.close(); Map> headerFields = conn.getHeaderFields(); List cookiesHeader = headerFields.get(COOKIES_HEADER); if (cookiesHeader != null) { for (String cookie : cookiesHeader) { msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0)); } } setResponseCode(conn.getResponseCode()); if (getResponseCode() == HttpsURLConnection.HTTP_OK) { String line; BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = br.readLine()) != null) { response += line; } } else { response = ""; } } catch (Exception e) { e.printStackTrace(); } return response; } // HTTP GET request public static String sendGet(String url) throws Exception { URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // optional default is GET con.setRequestMethod("GET"); //add request header con.setRequestProperty("User-Agent", "Mozilla"); /* * https://stackoverflow.com/questions/16150089/how-to-handle-cookies-in-httpurlconnection-using-cookiemanager * Get Cookies form cookieManager and load them to connection: */ if (msCookieManager.getCookieStore().getCookies().size() > 0) { //While joining the Cookies, use ',' or ';' as needed. Most of the server are using ';' con.setRequestProperty(COOKIE , TextUtils.join(";", msCookieManager.getCookieStore().getCookies())); } /* * https://stackoverflow.com/questions/16150089/how-to-handle-cookies-in-httpurlconnection-using-cookiemanager * Get Cookies form response header and load them to cookieManager: */ Map> headerFields = con.getHeaderFields(); List cookiesHeader = headerFields.get(COOKIES_HEADER); if (cookiesHeader != null) { for (String cookie : cookiesHeader) { msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0)); } } int responseCode = con.getResponseCode(); BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); return response.toString(); } public static void setResponseCode(int responseCode) { WebService.responseCode = responseCode; Log.i("Milad", "responseCode" + responseCode); } public static int getResponseCode() { return responseCode; } } 

Я не работаю с Google Android, но я думаю, вы обнаружите, что это не так сложно заставить это работать. Если вы прочитаете соответствующий бит учебника java, вы увидите, что зарегистрированный обработчик cookie получает обратные вызовы из кода HTTP.

Итак, если нет значения по умолчанию (вы проверили, действительно ли CookieHandler.getDefault() действительно null?), Тогда вы можете просто расширить CookieHandler, реализовать put / get и заставить его работать почти автоматически. Не забудьте рассмотреть параллельный доступ и тому подобное, если вы идете по этому маршруту.

edit: Очевидно, вам нужно будет установить экземпляр вашей пользовательской реализации в качестве обработчика по умолчанию через CookieHandler.setDefault() для получения обратных вызовов. Забыл упомянуть об этом.

  • Ограничить десятичные места в Android EditText
  • Android: укажите два разных изображения для переключателя с использованием XML
  • com.android.build.transform.api.TransformException
  • Как получить String Array из файла arrays.xml
  • Как удалить определенный элемент из JSONArray?
  • Создайте PDU для Android, который работает с SmsMessage.createFromPdu () (GSM 3gpp)
  • Быстрое размытие растровых изображений для Android SDK
  • как получить максимальное значение из списка / ArrayList
  • TransformException дубликат записи для common.annotations.Beta
  • Пауза / остановка и запуск / возобновление Java TimerTask непрерывно?
  • Android Как прослушивать события кнопки громкости?
  • Interesting Posts

    Массив Unnest на один уровень

    WPF / MVVM – как обрабатывать двойной щелчок на TreeViewItems в ViewModel?

    Поиск текста веб-страниц с использованием истории браузера в хроме?

    Visual Studio 2012 __cplusplus и C ++ 11

    Помните, какая вкладка была активной после обновления

    Обновление библиотеки поддержки Android до 23.2.0 вызывает ошибку: XmlPullParserException Бинарная строка XML-файла # 17 требует viewportWidth> 0

    R: извлечение «чистого» текста UTF-8 с веб-страницы, очищенной с помощью RCurl

    Windows 7 висит на черном экране некоторое время после входа в систему

    Разница между виртуальной функцией и чистой виртуальной функцией

    Какой из них лучше pushstate или location.hash?

    Entity Framework: Где я могу расширить CSDL / MSL?

    Что означает поддержка «Legacy USB Mouse» в BIOS?

    Как изменить значение по умолчанию для совместного использования экрана / номера порта VNC в Mac OS X?

    Такая же политика происхождения и CORS (совместное использование ресурсов)

    Django: группа по дате (день, месяц, год)

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