android实现session保持简要概述及实现
程序员文章站
2023-12-12 19:14:58
在最近写的一个android中需要请求web服务器中的数据,有一个登录activity,登录后会到mainactivity,这中间登录和mainactivity都需要请求p...
在最近写的一个android中需要请求web服务器中的数据,有一个登录activity,登录后会到mainactivity,这中间登录和mainactivity都需要请求php的jsonapi,所以要在网络请求中保持session的,研究了好半天才搞定。其实sesion在浏览器和web服务器直接是通过一个叫做name为sessionid的cookie来传递的,所以只要在每次数据请求时保持sessionid是同一个不变就可以用到web的session了,做法是第一次数据请求时就获取sessionid的值并保存在一个静态变量中,然后在第二次请求数据的时候要将这个sessionid一并放在cookie中发给服务器,服务器则是通过这个sessionid来识别究竟是那个客户端在请求数据的,在php中这个sessionid的名字叫做phpsessid。下面贴下代码
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了,而是叫做别的名字了,这个可能要具体情况去查了。
其实不只是android程序,其他任何程序需要这么用的时候只需要在http协议请求header里头加上发送相应的sessionid就可以了。刚刚这种方法是可以帮助理解sessionid的,其实还有一种方法如果更通用的话,就可以将刚刚所有的cookie每次都发回到服务器端,也就可以解决session保持的问题了,只是这样可能会稍微大些网络流量开销而已。
这里看到一个sessionid的本质,顺便mark一下。
sessionid的本质
一、客户端用cookie保存了sessionid
客户端用cookie保存了sessionid,当我们请求服务器的时候,会把这个sessionid一起发给服务器,服务器会到内存中搜索对应的sessionid,如果找到了对应的 sessionid,说明我们处于登录状态,有相应的权限;如果没有找到对应的sessionid,这说明:要么是我们把浏览器关掉了(后面会说明为什 么),要么session超时了(没有请求服务器超过20分钟),session被服务器清除了,则服务器会给你分配一个新的sessionid。你得重 新登录并把这个新的sessionid保存在cookie中。
在没有把浏览器关掉的时候(这个时候假如已经把sessionid保存在cookie中了)这个sessionid会一直保存在浏览器中,每次请求的时候都会把这个sessionid提交到服务器,所以服务器认为我们是登录的;当然,如果太长时间没有请求服务器,服务器会认为我们已经所以把浏览器关掉了,这个时候服务器会把该sessionid从内存中清除掉,这个时候如果我们再去请求服务器,sessionid已经不存在了,所以服务器并没有在内存中找到对应的 sessionid,所以会再产生一个新的sessionid,这个时候一般我们又要再登录一次。
二、客户端没有用cookie保存sessionid
这 个时候如果我们请求服务器,因为没有提交sessionid上来,服务器会认为你是一个全新的请求,服务器会给你分配一个新的sessionid,这就是 为什么我们每次打开一个新的浏览器的时候(无论之前我们有没有登录过)都会产生一个新的sessionid(或者是会让我们重新登录)。
当我们一旦把浏览器关掉后,再打开浏览器再请求该页面,它会让我们登录,这是为什么?我们明明已经登录了,而且还没有超时,sessionid肯定还在服 务器上的,为什么现在我们又要再一次登录呢?这是因为我们关掉浏览再请求的时候,我们提交的信息没有把刚才的sessionid一起提交到服务器,所以服务器不知道我们是同一个人,所以这时服务器又为我们分配一个新的sessionid,打个比方:浏览器就好像一个要去银行开户的人,而服务器就好比银行, 这个要去银行开户的人这个时候显然没有帐号(sessionid),所以到银行后,银行工作人员问有没有帐号,他说没有,这个时候银行就会为他开通一个帐 号。所以可以这么说,每次打开一个新的浏览器去请求的一个页面的时候,服务器都会认为,这是一个新的请求,他为你分配一个新的sessionid。
复制代码 代码如下:
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了,而是叫做别的名字了,这个可能要具体情况去查了。
其实不只是android程序,其他任何程序需要这么用的时候只需要在http协议请求header里头加上发送相应的sessionid就可以了。刚刚这种方法是可以帮助理解sessionid的,其实还有一种方法如果更通用的话,就可以将刚刚所有的cookie每次都发回到服务器端,也就可以解决session保持的问题了,只是这样可能会稍微大些网络流量开销而已。
这里看到一个sessionid的本质,顺便mark一下。
sessionid的本质
一、客户端用cookie保存了sessionid
客户端用cookie保存了sessionid,当我们请求服务器的时候,会把这个sessionid一起发给服务器,服务器会到内存中搜索对应的sessionid,如果找到了对应的 sessionid,说明我们处于登录状态,有相应的权限;如果没有找到对应的sessionid,这说明:要么是我们把浏览器关掉了(后面会说明为什 么),要么session超时了(没有请求服务器超过20分钟),session被服务器清除了,则服务器会给你分配一个新的sessionid。你得重 新登录并把这个新的sessionid保存在cookie中。
在没有把浏览器关掉的时候(这个时候假如已经把sessionid保存在cookie中了)这个sessionid会一直保存在浏览器中,每次请求的时候都会把这个sessionid提交到服务器,所以服务器认为我们是登录的;当然,如果太长时间没有请求服务器,服务器会认为我们已经所以把浏览器关掉了,这个时候服务器会把该sessionid从内存中清除掉,这个时候如果我们再去请求服务器,sessionid已经不存在了,所以服务器并没有在内存中找到对应的 sessionid,所以会再产生一个新的sessionid,这个时候一般我们又要再登录一次。
二、客户端没有用cookie保存sessionid
这 个时候如果我们请求服务器,因为没有提交sessionid上来,服务器会认为你是一个全新的请求,服务器会给你分配一个新的sessionid,这就是 为什么我们每次打开一个新的浏览器的时候(无论之前我们有没有登录过)都会产生一个新的sessionid(或者是会让我们重新登录)。
当我们一旦把浏览器关掉后,再打开浏览器再请求该页面,它会让我们登录,这是为什么?我们明明已经登录了,而且还没有超时,sessionid肯定还在服 务器上的,为什么现在我们又要再一次登录呢?这是因为我们关掉浏览再请求的时候,我们提交的信息没有把刚才的sessionid一起提交到服务器,所以服务器不知道我们是同一个人,所以这时服务器又为我们分配一个新的sessionid,打个比方:浏览器就好像一个要去银行开户的人,而服务器就好比银行, 这个要去银行开户的人这个时候显然没有帐号(sessionid),所以到银行后,银行工作人员问有没有帐号,他说没有,这个时候银行就会为他开通一个帐 号。所以可以这么说,每次打开一个新的浏览器去请求的一个页面的时候,服务器都会认为,这是一个新的请求,他为你分配一个新的sessionid。