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的技术来保 ...
随机推荐
- Android IOS WebRTC 音视频开发总结(十七)-- 调试技巧
本文章主要介绍WEBRTC在各平台下调试或日志查看方式,以方便问题排查,包括BS,PC,Android,IOS(本系列文章转载请说明出处,博客园RTC.Blacker). 1,浏览器开发: 这种开发方 ...
- Jqgrid获取行id
//获取选中行(单行)的ID var id = $("#table").jqGrid('getGridParam','selrow'); //根据id获取行数据,返回的是列表 va ...
- 内核linux-3.4.2支持dm9000
当前烧写: fs: nfs 30000000 192.168.1.17:/work/nfs_root/first_fs_mdev.yaffs2 //这里不能使用nfs挂载,只能直 ...
- 树莓派 B+ Yeelink实现图像监控
树莓派 B+ Yeelink实现图像监控 数值传感器请参考 : http://blog.csdn.net/xiabodan/article/details/39084877 1 安装摄像头 ...
- Objective-C中的self和super
1.有过面向对象的人知道,self相当于this,super相当于调用父类的方法 2.self是类的隐藏的参数,指向当前调用方法的类,另一个隐藏参数是_cmd,代表当前类方法的selector. su ...
- silverlight 不能输入中文问题
<param name="Windowless" value="true" />将调用silverlight页面的这句删除掉应该就能解决问题了 1. ...
- mariadb DML语句及用户授权
DML(Data Manipulation Language):INSERT, DELETE, UPDATE, SELECT INSERT [INTO] tbl_name [(col1,...) ...
- HBase分布式安装
安装HBase之前需要先安装Hadoop,因为HBase是运行在Hadoop集群上的.安装Hadoop可以参照http://www.cnblogs.com/stGeekpower/p/3307289. ...
- 获取php的配置
ini_get — 获取一个配置选项的值 返回值 成功是返回配置选项值的字符串,null 的值则返回空字符串.如果配置选项不存在,将会返回 FALSE. <?php /* 我们的 php.ini ...
- 1)C++对象大小计算
C++对象的大小不同的编译器的实现是不一样的,以下仅讨论.net2003,其他编译的可能出现的结果以下也做了分析和猜测.在反推不同编译器实现的C++对象的大小时.对齐是一个很重要也容易被遗 ...