大家在电脑上登录网上购物商城的时候购物,先进行登录,输入用户名密码,然后看到自己中意的商品就点开它的详情页面查看详细参数,然后决定买不买,在打开详情页面的时候,页面已经实现了跳转,那么第二个页面是服务器怎么知道你就是之前登录的的那个人呢??这里用到了session会话,在登录的时候输入用户名密码,服务器会返回一个session值,登录成功以后访问其他页面,浏览器会自动带着之前服务器分配给你的session值去访问服务器的其他接口,这样,其他接口看到了你拿的这个session值,就知道此时的你就是之前登录的那个人了,下面以谷歌浏览器为例,来看看浏览器是怎么折腾这个session值的。
我先访问登录接口,截图如下:
我将用户名密码作为参数携带,访问登陆接口,登陆成功,右侧一栏捕捉到的信息如图所示,在“headers”标签下,在“Response Headers”中,可以看到键为“Set-Cookie”,值为”JSESSIONID=XXXXXXXXXXXX”的键值对,当然,后面的那个“Path=/”暂时忽略,这里的意思就是你登录成功啦,服务器返回的响应头里面存储了SESSION的信息,而这个信息就在”Set-Cookie”中,紧接着我们访问获取个人信息的接口,如图所示:
我并没有携带任何参数去访问获取个人信息接口,但是服务器就是很准确的把我之前登录过的账号的信息返回了回来,可以看到屏幕左边有一串JSON数据,然后再看右边的“headers”标签下,在“Request Headers”标签下,即请求头标签下,我们可以看到以“Cookie”为键,“JSESSIONID=XXXXXXXX”为值的键值对,而且“JSESSIONID”后面的数值和第一次登陆的时候服务器返回的JSESSIONID的值一样,这说明了,谷歌浏览器自动的保存了服务器返回给我们的“Set-Cookie”的值,并且在以后的访问接口的过程中,把值加到了“Cookie”这个键上面,Android客户端也是一样,第一次登录的时候获取“Set-Cookie”的值,把这个值保存在本地,在以后的访问接口过程中把存在本地的值取出来,然后加到请求头上面就可以了。下面看代码:
MainActivity代码:
public class MainActivity extends Activity {
//登录的接口,顺便把用户名密码带上去,直接访问接口即可
public static final String login_url="http://192.168.1.110:8090/ehetu_common/login.action?userName=18215199999&password=123456";
//获取个人信息的接口
public static final String getUserInfo_url="http://192.168.1.110:8090/ehetu_common/getUserInfo.action";
private TextView tv_response,tv_jsessionid;
private SharedPreferences preference;
private SharedPreferences.Editor editor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_response=(TextView) findViewById(R.id.tv_response);
tv_jsessionid=(TextView) findViewById(R.id.tv_jsessionid);
preference=getSharedPreferences("cookie", MODE_PRIVATE);
editor=preference.edit();
}
//访问登录接口
public void login(View v){
new Thread(){
public void run() {
try {
URL url=new URL(login_url);
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
InputStream is=con.getInputStream();
//注意这里获取服务器返回的头部信息,获取JSESSIONID=XXXXXX的信息
final String cookieString=con.getHeaderField("Set-Cookie");
//然后保存在本地
editor.putString("jsessionid", cookieString);
editor.commit();
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[]buffer=new byte[1024];
int len=0;
while((len=is.read(buffer))>0){
bos.write(buffer,0,len);
}
bos.flush();
is.close();
byte []result=bos.toByteArray();
final String res=new String(result);
runOnUiThread(new Runnable() {
public void run() {
tv_response.setText(res);
tv_jsessionid.setText(cookieString);
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
}
//访问获取个人信息的接口
public void getUserInfo(View v){
new Thread(){
public void run() {
try {
URL url=new URL(getUserInfo_url);
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
//注意,把存在本地的cookie值加在请求头上
con.addRequestProperty("Cookie", preference.getString("jsessionid", ""));
InputStream is=con.getInputStream();
ByteArrayOutputStream bos=new ByteArrayOutputStream();
byte[]buffer=new byte[1024];
int len=0;
while((len=is.read(buffer))>0){
bos.write(buffer,0,len);
}
bos.flush();
is.close();
byte []result=bos.toByteArray();
final String res=new String(result);
runOnUiThread(new Runnable() {
public void run() {
tv_response.setText(res);
}
});
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
}
}
activity_main.xml代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="15dip" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="login"
android:text="访问登录接口,获取信息" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="getUserInfo"
android:text="访问获取个人信息的接口" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="服务器返回的信息:"
android:textColor="#000"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_response"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="服务器返回的JSESSIONID的信息:"
android:textColor="#000"
android:textSize="17sp" />
<TextView
android:id="@+id/tv_jsessionid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:textSize="15sp" />
</LinearLayout>
这是运行程序效果图:
可以看到,主界面主要是两个按钮,一个按钮触发用户登录事件,并且把服务器端返回头里面”Set-Cookie”这个键对应的值利用SharedPreferences保存在本地,在点击第二个按钮获取个人信息的时候,再从本地取出来,加到请求头上面。这是点击登录按钮之后的截图:
这是点击获取个人信息之后的截图:
可以看到,服务器把个人信息都返回回来了。