Android -- 与WEB交互在同一个会话Session中通信
Session与Cookie
Cookie和Session都为了用来保存状态信息,都是保存客户端状态的机制,它们都是为了解决HTTP无状态的问题而所做的努力。
Session可以用Cookie来实现,也可以用URL回写的机制来实现。
Cookie和Session有以下明显的不同点:
1)Cookie将状态保存在客户端,Session将状态保存在服务器端;
2)Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器。网络服务器用HTTP头向客户端发送cookies,在客户终端,浏览器解析这些cookies并将它们保存为一个本地文件,它会自动将同一服务器的任何请求缚上这些cookies。
3)Session是针对每一个用户的,变量的值保存在服务器上,用一个sessionID来区分是不同用户session变量,这个值是通过用户的浏览器在访问的时候返回给服务器,当客户禁用cookie时,这个值也可能设置为由get来返回给服务器;
4)就安全性来说:当你访问一个使用session 的站点,同时在自己机器上建立一个cookie,建议在服务器端的SESSION机制更安全些.因为它不会任意读取客户存储的信息。
Session机制
Session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为 session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个 session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id将被在本次响应中返回给客户端保存。
Session的实现方式
1)使用Cookie来实现
服务器给每个Session分配一个唯一的JSESSIONID,并通过Cookie发送给客户端。
当客户端发起新的请求的时候,将在Cookie头中携带这个JSESSIONID。这样服务器能够找到这个客户端对应的Session。
2)使用URL回显来实现
URL回写是指服务器在发送给浏览器页面的所有链接中都携带JSESSIONID的参数,这样客户端点击任何一个链接都会把JSESSIONID带给服务器。
如果直接在浏览器中输入url来请求资源,Session是匹配不到的。
Tomcat对 Session的实现,是一开始同时使用Cookie和URL回写机制,如果发现客户端支持Cookie,就继续使用Cookie,停止使用URL回写。如果发现Cookie被禁用,就一直使用URL回写。jsp开发处理到Session的时候,对页面中的链接记得使用 response.encodeURL() 。
手机端与服务器交互没有实现在同一session下?
原因很简单,就是因为android手机端在访问web服务器时,没有给http请求头部设置sessionID,而使用web浏览器作为客户端访问服务器时,在客户端每次发起请求的时候,都会将交互中的sessionID:JSESSIONID设置在Cookie头中携带过去,服务器根据这个sessionID获取对应的Session,而不是重新创建一个新Session(除了这个Session失效)。
Code(1) HttpURLConnection实现
URL url = new URL(requrl);
HttpURLConnection con= (HttpURLConnection) url.openConnection();
// 取得sessionid.
String cookieval = con.getHeaderField("set-cookie");
String sessionid;
if(cookieval != null) {
sessionid = cookieval.substring(0, cookieval.indexOf(";"));
}
//sessionid值格式:JSESSIONID=AD5F5C9EEB16C71EC3725DBF209F6178,是键值对,不是单指值
发送设置cookie:
URL url = new URL(requrl);
HttpURLConnectioncon= (HttpURLConnection) url.openConnection();
if(sessionid != null) {
con.setRequestProperty("cookie", sessionid);
}
Code(2) HttpClient 单例模式实现
只要存在一个HttpClient对象就可以了,这个HttpClient对象中就包含得有Cookie信息。
我在工程中是使用的单例模式实现的:
public class Client {
private static HttpClient instance = null; private Client() { } public static HttpClient getInstance() {
if (instance == null) {
return instance = new DefaultHttpClient();
} else {
return instance;
}
}
}
class myThread extends Thread { @Override
public void run() {
try {
HttpClient client = Client.getInstance(); String path = "http://192.168.1.4/zxx/test.php";
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
httpPost.setEntity(new UrlEncodedFormEntity(param, "utf-8"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}finally
{ }
super.run();
}
} class myThread2 extends Thread { @Override
public void run() {
try {
HttpClient client = Client.getInstance(); String path = "http://192.168.1.4/zxx/test1.php";
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000")); HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
}
两个线程中就可以使用同一个cookie访问了。
Code(3) SeesionId Url传递实现
通过将SessionId的值通过url传递到想继续在同一会话中访问的页面。
php代码:test2.php
<?php
session_start();
header("Content-type:text/html;charset=utf-8"); if(isset($_POST['phonenumber']))
{
$phone = $_POST['phonenumber'];
if(!isset($_SESSION['phone']))
{
$time=time()+60*10*10;//100分钟
$_SESSION['phone'] = $phone;
echo session_id();
}
else
echo "POST phone already exist";
}
if(isset($_GET['phonenumber']))
{
$phone = $_GET['phonenumber'];
if(!isset($_SESSION['phone']))
{
$time=time()+60*10*10;//100分钟
$_SESSION['phone'] = $phone;
echo session_id();
}
else
echo "GET phone already exist";
} ?>
test3.php
Session_id($_GET['id']);
session_start();
header("Content-type:text/html;charset=utf-8"); if(isset($_POST['phonenumber']))
{
$phone = $_POST['phonenumber'];
echo "phone-->".$phone."<br />";
echo "_SESSION[phone]-->".$_SESSION['phone']."<br />";
echo "SESSIONid--->".session_id();
if($_SESSION['phone'] == $phone)
echo "POST 验证 OK";
else
echo "POST 验证 BAD"; }
if(isset($_GET['phonenumber']))
{
$phone = $_GET['phonenumber'];
echo "phone-->".$phone."<br />";
echo "_SESSION[phone]-->".$_SESSION['phone']."<br />";
echo "session_id--->".session_id();
if($_SESSION['phone'] == $phone)
echo "GET 验证 OK";
else
echo "GET 验证 BAD";
}
Android上的代码(这里我们分别new两个HttpClient做测试):
class myThread extends Thread { @Override
public void run() {
try {
client = new DefaultHttpClient(); String path = "http://192.168.1.4/zxx/test.php";
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
httpPost.setEntity(new UrlEncodedFormEntity(param, "utf-8"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
seesionId = SysOut;
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}finally
{ }
super.run();
}
} class myThread2 extends Thread { @Override
public void run() {
try {
client = new DefaultHttpClient(); String path = "http://192.168.1.4/zxx/test1.php?id="+seesionId;
HttpPost httpPost = new HttpPost(path);
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("phonenumber", "18200000000"));
httpPost.setEntity(new UrlEncodedFormEntity(param, "utf-8"));
HttpResponse response = client.execute(httpPost);
int code = response.getStatusLine().getStatusCode();
if (code == 200) {
InputStream is = response.getEntity().getContent();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
is.close();
baos.close();
byte[] result = baos.toByteArray();
String SysOut = new String(result, "utf-8");
System.out.println(SysOut);
} else {
System.out.println("code----------->" + code + "");
}
} catch (Exception e) {
e.printStackTrace();
}
super.run();
}
}
Session_id($_GET['id']); 这句话很重要。
我是天王盖地虎的分割线
Android -- 与WEB交互在同一个会话Session中通信的更多相关文章
- web后台获取不到session中的值(loading sessions from persistent storage),后改用JS传值
线上的程序似乎从session中取不到domain数据,重启了一下tomcat查看log日志发现,居然有报错.错误信息如下 22-Sep-2016 00:52:16.562 SEVERE [local ...
- Java web课程学习之会话(Session)
Session会话 l web应用中的会话是指一个客户端浏览器与web服务器之间连续发生一系列请求和响应过程 l web应用的会话状态是指web服务器与浏览器在会话过程中产生的状态信息,借助会话状 ...
- web跨域访问,session丢失的问题
web跨域访问,session丢失的问题25 http://www.iteye.com/problems/71265 http://www.iteye.com/topic/264079 具体情况如下: ...
- WCF会话(Session)与实例(Instance)管理
一.理解Session 1.Session的作用:保留Client和Service之间交互的状态,确保Client与Service之间交互唯一性(SessionId),即:多个Client同时访问Se ...
- 简单PHP会话(session)说明
现在程序员愈发的不容易了,想要精通,必然要寻本溯源,这其实与目前泛滥的愈发高级的语言以及众多的框架刚好相反,因为它们在尽可能的掩盖本源使其简单,个人称之为程序员学习悖论. 注:作者接触web开发和ph ...
- http 会话(session)详解
会话(session)是一种持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包的作用机制 一.查看session id 可利用相关工具,比如firebug,httpwatc ...
- 会话session
因为因特网HTTP协议的特性,每一次来自于用户浏览器的请求(request)都是无状态的.独立的.通俗地说,就是无法保存用户状态,后台服务器根本就不知道当前请求和以前及以后请求是否来自同一用户.对于静 ...
- 网络基础 http 会话(session)详解
http 会话(session)详解 by:授客 QQ:1033553122 会话(session)是一种持久网络协议,在用户(或用户代理)端和服务器端之间创建关联,从而起到交换数据包的作用机制 一. ...
- 会话(Session)与cookies
由于http是无状态的,向服务器发送请求后,服务器解析请求然后返回对应的响应,服务器负责完成这个过程是完全独立的,不会记录前后状态的变化,因此缺少状态记录. 我们分别需要会话和Cookies的技术来保 ...
随机推荐
- ruby中symbol
Symbol 是什么 Ruby 是一个强大的面向对象脚本语言(本文所用 Ruby 版本为1.8.6),在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字. 创建一个 Symb ...
- Hbase多master
单台master的配置 hbase.master master:60000 这是我们通常配置的,这样就定义了master是的ip和端口. 但是当我们需要配置多台master进行,我们只需要提供端口,因 ...
- .net分页控件webdiyer:AspNetPager
首先下载:AspNetPager.dll AspNetPager.xml 放到bin目录下 页面添加<%@ Register Assembly="AspNetPager" ...
- Android IOS WebRTC 音视频开发总结(十四)-- sip和xmpp异同
这篇文章主要介绍XMPP与SIP,很多人容易混淆这两个概念,转载请说明出处(博客园RTC.Blacker). 简介:XMPP和SIP都是应用层协议,主要用于互联网上发送语音和即时通讯. SIP在RFC ...
- SSDT Hook
一.效果图 二.分析 这里对NtCreateProcessEx做拦截,用WinDbg来定位该函数在SSDT中的记录地址: : kd> dd KeServiceDescriptorTable 80 ...
- Unable to add App ID because the '10' App ID limit in '7' days has been exceeded.
Unable to add App ID because the '10' App ID limit in '7' days has been exceeded. 官方的原因是对bundle iden ...
- s3c6410_u-boot-2010.03移植
开发环境: 开发板 FriendlyARM Tiny6410 主机 CentOS release 6.4 (Final) 参考: http://www.cnblogs.com/plinx/archiv ...
- iOS自动布局一
Align: Pin:
- php实现显示网站运行时间-秒转换年月日时分秒
<?php // 设置时区 date_default_timezone_set('Asia/Shanghai'); /** * 秒转时间,格式 年 月 日 时 分 秒 * * @author w ...
- Android四大组件一----Activity
最新面试需要复习一下Android基础. {所谓Activity} 通俗点:app上看到的窗口基本都是Activity Android 程序一般是由多个Activity组成,用户看到的能够交互的窗口通 ...