大家在电脑上登录网上购物商城的时候购物,先进行登录,输入用户名密码,然后看到自己中意的商品就点开它的详情页面查看详细参数,然后决定买不买,在打开详情页面的时候,页面已经实现了跳转,那么第二个页面是服务器怎么知道你就是之前登录的的那个人呢??这里用到了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保存在本地,在点击第二个按钮获取个人信息的时候,再从本地取出来,加到请求头上面。这是点击登录按钮之后的截图: 这是点击获取个人信息之后的截图: 可以看到,服务器把个人信息都返回回来了。