在最近寫的一個Android中須要請求web服務器中的數據,有一個登陸Activity,登陸後會到MainActivity,這中間登陸和MainActivity都須要請求php的jsonapi,因此要在網絡請求中保持session的,研究了好半天才搞定。其實sesion在瀏覽器和web服務器直接是經過一個叫作name爲sessionid的cookie來傳遞的,因此只要在每次數據請求時保持sessionid是同一個不變就能夠用到web的session了,作法是第一次數據請求時就獲取sessionid的值並保存在一個靜態變量中,而後在第二次請求數據的時候要將這個sessionid一併放在Cookie中發給服務器,服務器則是經過這個sessionid來識別到底是那個客戶端在請求數據的,在php中這個sessionid的名字叫作PHPSESSID。下面貼下代碼 php
import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.List; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CookieStore; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; public class MyHttpClient implements InetConfig { private DefaultHttpClient httpClient; private HttpPost httpPost; private HttpEntity httpEntity; private HttpResponse httpResponse; public static String PHPSESSID = null; public LVHttpClient() { } public String executeRequest(String path, List<NameValuePair> params) { String ret = "none"; try { this.httpPost = new HttpPost(BASEPATH + path); httpEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8); httpPost.setEntity(httpEntity); //第一次通常是還未被賦值,如有值則將SessionId發給服務器 if(null != PHPSESSID){ httpPost.setHeader("Cookie", "PHPSESSID=" + PHPSESSID); } httpClient = new DefaultHttpClient(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } try { httpResponse = httpClient.execute(httpPost); if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { HttpEntity entity = httpResponse.getEntity(); ret = EntityUtils.toString(entity); CookieStore mCookieStore = httpClient.getCookieStore(); List<Cookie> cookies = mCookieStore.getCookies(); for (int i = 0; i < cookies.size(); i++) { //這裏是讀取Cookie['PHPSESSID']的值存在靜態變量中,保證每次都是同一個值 if ("PHPSESSID".equals(cookies.get(i).getName())) { PHPSESSID = cookies.get(i).getValue(); break; } } } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return ret; } }
其實web的原理都是同樣的,基於http協議的,那麼若是網站不是php作的話,那個叫作Sessionid的Cookie可能叫作別的了,就不是PHPSESSID了,而是叫作別的名字了,這個可能要具體狀況去查了。 html
其實不僅是Android程序,其餘任何程序須要這麼用的時候只須要在http協議請求header裏頭加上發送相應的SessionId就能夠了。剛剛這種方法是能夠幫助理解sessionid的,其實還有一種方法若是更通用的話,就能夠將剛剛全部的Cookie每次都發回到服務器端,也就能夠解決session保持的問題了,只是這樣可能會稍微大些網絡流量開銷而已。 java
這裏看到一個SessionId的本質,順便mark一下。 web