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

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中严格区分大小写。这些都是必须遵守的。
如果有比这个更好的方法,期待共同探讨。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值