`
herryhaixiao
  • 浏览: 90696 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

通过sessionId的方式使手机浏览支持session

    博客分类:
  • wap
阅读更多
   Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一SessionID提交到服务器端,来存取Session数据。所以一旦客户端禁用Cookie,那么Session也会失效。
   由于目前有的手机不支持cookie,导致手机上session支持不了,于是乎就有了几种针对这些特殊情况而提出的解决方案。而最常见的就是url重写,而url重写又分几种,有jstl实现,struts实现,普通传参实现,而我用的也就是最普通最常见的一种实现方式。
    其实我也是根据kaixin001中的方式来做的,kaixin001中的wap形式就是在链接后面直接传sessionId的方式(其中包括了用户的id,后面有串字符串,我猜想应该就是sessionId),比如:http://localhost:8080/project/MobileLogin.do?sessionId=xxxxxxxx;这个sessionId就是session的id,通过链接传参的方式传到后台,在后台,由于不支持session,故需要自己开发一套基于session的操作。
    首先,先了解下Map的含义,在java中,我们都知道Map是一个用于存储键值对的一个集合,也就是我们常说的key、value对应值,并且每个键映射一个值,这个键是不能重复的。
    上面了解了Map的含义,为什么要了解Map,是因为在接下来我需要在程序中用到Map。好了,言归正传,怎么才能实现sessionId取session的步骤呢,相信看了上面的Map,应该有人脑子里面有思路了,那就是利用Map的存储方式来操作sessionId,根据sessionId生成一个session,由于Map是key不能重复,所以就可以把sessionId设置成key,session设置为map的value,并且要保证这个sessionId永远都只需要创建一次,这就又用到了一个经典的设计模式:单例模式。第一次登录访问sessionId是新的,就往map中put一个,
public synchronized void sessionCreated(HttpSession session) {   
        
    	if(session != null) {   
        	map.put(session.getId(), session);   
        }   
    }   

除非你登录失败,否则这个sessionId一直跟随你的程序在运行,直到你手动注销session(把session destroryed)或者重新登录一次(替换原有的sessionId)。
public synchronized void sessionDestroyed(HttpSession session) {   
        
    	if(session != null) {   
        	map.remove(session.getId());   
        }   
    } 

单例模式的session容器已经构建,最后就是在类中提供一个getSession的方法;
public synchronized HttpSession getSession(String sessionId) {   
        
    	if(sessionId == null)
    		return null;   
        return (HttpSession) map.get(sessionId);   
    }   

session容器的构建类已经写完,现在就是监听事件了,新建一个Listener监听器,实现HttpSessionListener,HttpSessionListener提供2个方式,一个是sesionCreated(session的创建方法),一个是sessionDistoryed(session的销毁方法),在created方法中,调用单例类中的sessionCreate方法,在destroyed方法中调用单例类中的sessionDistoryed方法,监听器需要在web.xml中进行配置.
<listener>
           <listener-class>xxx包下的xxx类</listener-class>
    </listener>

至此,就完成了一个session的构建,并且这个session是根据sessionId的变化而变化。下面看具体的代码:
//session容器单例类

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;

public class SessionContext {

	private static SessionContext instance;   
    private Map<String, HttpSession> map;   
    
    private SessionContext() {   
    	map = new HashMap<String, HttpSession>();   
    }   
    
    public static SessionContext getInstance() {   
        
    	if(instance == null) {   
            instance = new SessionContext();   
        }   
        return instance;   
    }   
    
    public synchronized void sessionCreated(HttpSession session) {   
        
    	if(session != null) {   
        	map.put(session.getId(), session);   
        }   
    }   
    
    public synchronized void sessionDestroyed(HttpSession session) {   
        
    	if(session != null) {   
        	map.remove(session.getId());   
        }   
    }   
    
    public synchronized HttpSession getSession(String sessionId) {   
        
    	if(sessionId == null)
    		return null;   
        return (HttpSession) map.get(sessionId);   
    }   



}


//session监听器

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListener implements HttpSessionListener {

    private SessionContext sessionContext = SessionContext.getInstance();

    
	public void sessionCreated(HttpSessionEvent httpSessionEvent) {
		sessionContext.sessionCreated(httpSessionEvent.getSession());

	}

	public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
		sessionContext.sessionDestroyed(httpSessionEvent.getSession());		
	}
	

}

session容器构建好了,现在就是action的操作了,action中相对比较简单。
public String sessionId;	
	
	public HttpSession getWapSession() throws Exception {
		HttpSession session = SessionContext.getInstance().getSession(sessionId);
		return session;
	}
	
	public void delSession() throws Exception {
		SessionContext.getInstance().sessionDestroyed(getWapSession());
	}

	public void setWapAttribute(String key, Object value) throws Exception {
		this.getWapSession().setAttribute(key, value);
	}
	
	public String getSessionId() {
		return sessionId;
	}


	public void setSessionId(String sessionId) {
		this.sessionId = sessionId;
	}

通过session传值,setWapAttribute(key,value),在页面上同样还是用SessionContext.getInstance().getSession(sessionId)得到session,才能从session中getAttribute值,其中的sessionId从request请求中get出,目前我还在测试怎么让它支持EL表达式,所以页面上还是用的<%%>这种取值方法。
以上就是action的部分代码,sessionId指的是页面上session.getId(),通过URL参数的方式传到后台,http://localhost:8080/project/xxx.do?session=<%=session.getId()%>,链接是这样的。url是自己组装。这个url方式是仿照开心网中的手机版本(wml.kaixin001.com),至此,一个手机登录的session问题是完美解决了,这里没有加权限判断。只提供了处理手机的登录session问题,相信有了session,其余的对我们来说不是什么难点。后期有时间再来写权限验证。
    wap开发,页面展示必须是符合wml规范的文件,可以是jsp文件,只不过头部要把头部的contentType类型改成wml形式的,
<%@ page contentType="text/vnd.wap.wml;charset=utf-8"%>

然后
<?xml version="1.0"  encoding="utf-8" ?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
	<card id="" title="">
</card>
</wml>

记住一点,wml语法的一点就是一定要有结束标签,哪怕是用这样的<br>,在wml语法中也是错误的,必须要有结束。<br/>或者<br></br>,而且wml中严格区分大小写。这些都是必须遵守的。
    如果有比这个更好的方法,期待共同探讨。
分享到:
评论
7 楼 liweixw 2010-06-17  
herryhaixiao 写道
liweixw 写道
<c:url 用标签库中这个标签写Url 不就结了。。干嘛要自己去写。。
重定向就这样写
String url= response.encodeRedirectURL(request.getContextPath(+"/wap/Index_input.action");
response.sendRedirect(url);
自动会检查浏览器是否支持,如果不支持就会重写url  自动带上sessionid
我现在wap就是这样做的。。  楼主你这样我感觉有多余。  而且你还要维护哪个map。
???
楼主你这样写 有点误入子弟。。。

哦,弱弱的问下,请问你这种session要怎么管理呢?我看了你写的文章,90%是网络上抄袭的,还有就是没有写session的管理。我没有恶意,只是我想问下你session是怎么管理的,我还没用过项目中,只是在研究阶段,第一次做wap开发,没什么经验。既然你有这方面的经验,那么我虚心请教下你。


是的。我是网上找的资料,为了以后方便查阅,其实也就是一时兴起, 我原来考虑也和你一样,我是参考的网易是怎么做的,(wap.163.com opera访问的) 我发现在禁用cookie的时候url网易会自动带上这个sessionid。
综合我现在的项目实践 我是这样做的。
1.在jsp中涉及到url是用的是标签库 <c:url 标签 填写url(这个标签自动会检查浏览器是否支持cookie,支持就原样返回,不支持自动带上sessionid)
2。在涉及后台转发时候用 首先用response.encodeURL()方法重写,和上面的标签一样的功能;
3.后台重定向用response.encodeRedirectURL()方法重写后转发。


6 楼 herryhaixiao 2010-06-17  
mercyblitz 写道
如果浏览器不支持Cookie,就直接是URL rewrite就行了。

恩,知道了,是我多此一举了,我想复杂了。
5 楼 mercyblitz 2010-06-16  
如果浏览器不支持Cookie,就直接是URL rewrite就行了。
4 楼 Zahir 2010-06-15  
没有必要对session进行手动管理,encodeURL()就可以达到你上面的几十行代码的效果了。
另外singleton的实现有点问题
3 楼 herryhaixiao 2010-06-15  
liweixw 写道
<c:url 用标签库中这个标签写Url 不就结了。。干嘛要自己去写。。
重定向就这样写
String url= response.encodeRedirectURL(request.getContextPath(+"/wap/Index_input.action");
response.sendRedirect(url);
自动会检查浏览器是否支持,如果不支持就会重写url  自动带上sessionid
我现在wap就是这样做的。。  楼主你这样我感觉有多余。  而且你还要维护哪个map。
???
楼主你这样写 有点误入子弟。。。

哦,弱弱的问下,请问你这种session要怎么管理呢?我看了你写的文章,90%是网络上抄袭的,还有就是没有写session的管理。我没有恶意,只是我想问下你session是怎么管理的,我还没用过项目中,只是在研究阶段,第一次做wap开发,没什么经验。既然你有这方面的经验,那么我虚心请教下你。
2 楼 liweixw 2010-06-13  
楼主提到
   url重写又分几种,有jstl实现,struts实现,普通传参实现
普通实现应该就是
response.encodeURL(url);
可以了 。
 
1 楼 liweixw 2010-06-13  
<c:url 用标签库中这个标签写Url 不就结了。。干嘛要自己去写。。
重定向就这样写
String url= response.encodeRedirectURL(request.getContextPath(+"/wap/Index_input.action");
response.sendRedirect(url);
自动会检查浏览器是否支持,如果不支持就会重写url  自动带上sessionid
我现在wap就是这样做的。。  楼主你这样我感觉有多余。  而且你还要维护哪个map。
???
楼主你这样写 有点误入子弟。。。

相关推荐

    ASP源码—手机平板电脑三合一企业网站源码.zip

    在手机和平板电脑的适配上,这个源码可能采用了响应式设计,这是一种布局方式,允许网站根据访问设备的屏幕尺寸和方向自动调整布局。CSS3(层叠样式表第三版)的媒体查询是实现响应式设计的关键,它能针对不同设备...

    手机网上店

    4. **购物车功能**:ASP可以实现购物车逻辑,例如,当用户选择商品时,将商品ID和数量存储在会话(Session)对象中,保持状态直到用户完成交易。结账时,ASP会计算总价,处理支付接口调用,确保交易安全。 5. **...

    基于ASP的奥智手机数码商城购物系统.zip

    这通常通过Session对象来实现,每个用户有一个唯一的Session ID,记录其购物车内商品。用户可以随时查看、修改购物车,直至提交订单。 6. **订单处理** 当用户完成支付后,系统会生成订单,并通过电子邮件或短信...

    phpcms购物车

    每个用户在网站上活动时会被分配一个唯一的session ID,购物车数据与该ID关联,确保了数据的唯一性和用户间的隔离。 2. 数据结构设计: - **购物车数据结构**:购物车中的每个项目通常由商品ID、数量、单价、属性...

    ASP+ACCESS在线手机销售系统(论文+源代码+答辩PPT).zip

    这个系统为用户提供了一个便捷的在线平台,可以浏览、搜索、购买手机以及相关配件。以下是这个系统的核心知识点: 1. **ASP技术**:ASP是微软开发的一种服务器端脚本语言,用于创建动态交互式的网页。在ASP+ACCESS...

    20周Web应用程序设计(ASP[1].NET)试卷A卷借鉴.pdf

    11. **SessionID**:ASP.NET为每个用户分配一个SessionID,当用户在应用内浏览不同页面时,这个ID保持不变,用于跟踪用户会话。 12. **Access数据库操作**:在ASP.NET中访问Access数据库,需要引入System.Data.Ole...

    基于ASP的无忧ASP企业网站系统 (带手机版).zip

    这个系统特别强调其移动端的支持,意味着它具备响应式设计或者独立的移动版本,可以适应不同设备的浏览需求,包括手机和平板等。 【描述分析】 描述中提到的 "基于ASP的无忧ASP企业网站系统 (带手机版).zip" 与标题...

    ASP论坛网站实例开发源码——PHP生成HTML文本论坛实例开发.zip

    7. 响应式设计:现代论坛需要支持多种设备,包括桌面电脑、平板和手机。因此,开发时需采用响应式布局,确保论坛在不同设备上都能良好显示。 8. 管理员后台:管理员后台是论坛维护的重要部分,包括用户管理、帖子...

    ecmallpnWx2_2H

    - **Session_id**:会话ID。 - **Store_id**:店铺ID。 - **Goods_id**:商品ID。 - **Goods_name**:商品名称。 - **Spec_id**:规格ID。 - **Specification**:规格描述。 - **Price**:价格。 - **Quantity**:...

    ASP淘宝网站形式设计与实现(论文+源代码).rar

    登录成功后,用户的ID或其他标识信息可以存储在`Session("变量名")`中,后续请求可以通过检查`Session`对象来判断用户是否已登录。 4. **商品展示与搜索**:ASP可以通过查询数据库来获取商品信息,并在页面上展示。...

    黑莓 9900 186号专用

    每个服务都有一个唯一的CSD(Client Session Descriptor),通过ServiceBook,手机可以自动配置和管理这些服务。 4. **Net_Wap9201**: Net_Wap9201可能代表的是一个网络服务,尤其是WAP(Wireless Application ...

    ASP动态网站 网店

    它支持SQL语法,能够存储、管理和检索数据。在ASP网店系统中,Access数据库通常用于存储商品信息、用户数据、订单详情等关键信息。 设计一个ASP动态网店,首先需要规划数据库结构。例如,可能需要创建以下几个表: ...

    基于JavaWeb的水果商城设计【论文】.doc

    系统应提供丰富的水果商品信息供用户浏览,并支持按条件筛选、搜索等功能。当用户确定购买意向后,可以将商品添加至购物车中。 - **商品展示**:商品图片、名称、价格、库存量等信息。 - **筛选条件**:价格区间、...

    使用ASP.NET技术开发网上书店(ASP.NET)

    对于网上书店,我们需要确保页面布局在手机和平板上也能正确显示,使用户能方便地浏览和购买图书。 最后,测试和调试是开发过程中不可或缺的部分。ASP.NET提供了多种工具,如Visual Studio的调试器,以及单元测试和...

    JSP+SQL server网上书店源码

    本项目是一个基于JSP技术和SQL Server数据库的简单网上书店系统,旨在提供用户在线浏览、购买图书以及管理购物车的功能。在这个系统中,JSP作为前端展示界面,负责与用户交互,而SQL Server则作为后台数据库,存储并...

    ASP制作的购物车源码

    在ASP中,这通常通过发送Ajax请求到服务器,服务器端接收请求后将商品信息(如ID、名称、价格等)存储到会话(Session)或数据库中。会话对象在用户浏览器会话期间保持数据,方便跟踪用户购物车中的商品。 2. **...

    asp.net mvc5课程设计 在线书店 包括分页、购物车、订单等功能

    在ASP.NET MVC5中,购物车通常通过Session或Cookie存储在客户端,或者在服务器端数据库中。购物车状态的管理可以通过控制器方法处理,而视图则用于展示购物车内容。 4. **订单处理**:订单功能包括订单创建、支付...

    网上家电销售管理系统的设计与实现

    考虑到用户可能通过不同设备访问,系统设计时应考虑响应式布局,确保在手机、平板电脑和桌面电脑上都有良好的显示效果。 总之,《网上家电销售管理系统的设计与实现》项目是一个综合运用ASP技术、数据库管理和Web...

    ASP源码—XYCMS ASP教育培训网站建站系统 v6.0.zip

    7. **响应式布局**:适应不同设备的浏览需求,无论是电脑还是手机、平板都能良好展示。 【ASP源码分析】 在ASP源码中,开发人员通常会使用VBScript或JScript作为脚本语言。源码包含了HTML、CSS、JavaScript以及...

Global site tag (gtag.js) - Google Analytics