如何使用Android上的cookie发出http请求?

我想在正确处理cookie(例如存储服务器发送的cookie,并在发出后续请求时发送这些cookie)的同时向远程服务器发出http请求。 这将是很好的保存任何和所有的cookie,但真正的唯一我关心的是会话cookie。

在java.net中,看起来这样做的首选方法是使用java.net.CookieHandler(抽象基类)和java.net.CookieManager(具体实现)。 Android有java.net.CookieHandler,但是它似乎没有java.net.CookieManager。

我可以通过检查http头来手工编码,但似乎必须有一个更简单的方法。

在保留cookie的同时在Android上进行http请求的正确方法是什么?

事实certificate,谷歌Android与Apache HttpClient 4.0,我能弄清楚如何使用HttpClient文档中的“基于表单login”的例子:

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<Cookie> 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 <NameValuePair> nvps = new ArrayList <NameValuePair>(); 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头。 您可以在使用apache库或使用HTTPUrlConnection进行HTTP调用时始终进行设置。 无论哪种方式,你应该能够以这种方式读取和设置HTTP cookie。

你可以阅读这篇文章的更多信息。

我可以分享我的代码和平,以certificate你是多么容易做到这一点。

 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 ,我写了这个类来发送获取和发布请求与这个答案的帮助:

 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<String, List<String>> headerFields = conn.getHeaderFields(); List<String> 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<String, List<String>> headerFields = con.getHeaderFields(); List<String> 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; } } 

我不工作与谷歌机器人,但我认为你会发现这并不难,得到这个工作。 如果您阅读了java教程的相关部分,您将看到一个注册的cookiehandler从HTTP代码中获取callback。

所以,如果没有默认的(你有没有检查CookieHandler.getDefault()真的是空?),那么你可以简单地扩展CookieHandler,实现put / get,并使其几乎自动工作。 如果你走这条路线,一定要考虑并发访问等。

编辑:显然你必须通过CookieHandler.setDefault()来设置你的自定义实现的实例作为默认处理程序来接收callback。 忘了提到这一点。