在JSP+Servlet中使用会话跟踪技术的代码框架

Web应用创建于HTTP之上,这会有一个严重的问题,即HTTP是一个无状态的协议,每个请求和相应都是独立的。如果没有会话管理,每次客服端向服务器端发起一个请求,服务器端都不会记录有关客户的任何信息。从服务器度端的角度看,一个新的请求就是一个新的用户,这个请求和其它请求也没有任何关系。为了解决这个问题,在web中引入了会话(session)的概念。

一个会话(session)是指从客户端发起第一个请求开始,即一个会话的开始时刻,到这个会话终止时刻的客户端与服务端的整个交互过程。

那么怎样保存客户端与服务端的会话状态信息呢,下面介绍两种方法。

1.利用cookies跟踪会话
当应用服务器第一次接收到一个请求时(如自定义的url参数action为none),先为该用户分配一个唯一的sessionid;或者也可以自己写一个函数),将该sessionid添加到用户的cookies中;此后每次接收到请求时,就从该请求用户的cookies中读取sessionid,这时如果没有成功读取,这就说明该用户不是通过默认的url来访问的,此时的处理方法就要根据网站的具体应用来决定了,如你可以跳转到自定义的错误页面,提示他通过默认的url登录,也可以把这个请求看成第一个请求来处理。
servlet的代码框架如下:

 

import  java.io.IOException;
import  java.util.Hashtable;

import  javax.servlet. * ;
import  javax.servlet.http. * ;
public   class  CController  extends  HttpServlet
{
    
//在这里声明所用到的模型对象
    
//private Hashtable<String,SessionData> sessionDataTable=new Hashtable<String,SessionData>();
    
//...
    public void init() throws ServletException 
    
{
        
//在这里添加其他资源的初始化代码(如数据库连接)
        
//...
    }

    
public void destroy()
    
{
        
//在这里添加收回其他资源的代码(如关闭数据库连接)
        
//...
    }

    
//Process the HTTP Get request  
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException 
    
{
        String action
=request.getParameter("action");
        String jspPage
="/index.jsp";
        
if(action==null||action.length()<1)
        
{
            action
="none";
        }

        
if(action.equals("none"))
        
{
            
//第一次请求,分配一个唯一分配的sessionid,或者也可以自定义函数(推荐)
            HttpSession session = request.getSession();
            String sessionId
=request.getRequestedSessionId();
            
            
//将会话数据对象添加到自定义的Hashtable中
            
//sessionDataTable.put(sessionId,new SessionData());
            
            
//将sessionid添加到用户cookies中(这里可设置path和cookies有效时间)
            response.addCookie(new Cookie("JSESSIONID",sessionId));
            request.setAttribute(
"sessionid", sessionId);
        }

        
else if(action.equals("home"))
        
{
            
//从用户cookies中读取sessionid
            Cookie[] c=request.getCookies();
            String sessionId
="";
            
for(int i=0;i<c.length;i++)
            
{
                
if(c[i].getName().equals("JSESSIONID"))
                
{
                    sessionId
=c[i].getValue();
                }

            }

            
if(!sessionId.equals(""))
            
{
                
//读取session数据对象
                
//SessionData data=sessionDataTable.get(sessionId);
                
//其他处理...
            }

            
else
            
{
                jspPage
="error.html";
            }

        }

        
else if(action.equals("xxx"))
        
{
            Cookie[] c
=request.getCookies();
            String sessionId
="";
            
for(int i=0;i<c.length;i++)
            
{
                
if(c[i].getName().equals("JSESSIONID"))
                
{
                    sessionId
=c[i].getValue();
                }

            }

            
if(!sessionId.equals(""))
            
{
                
//读取session数据对象
                
//SessionData data=sessionDataTable.get(sessionId);
                
//其他处理...
            }

            
else
            
{
                jspPage
="error.html";
            }

        }

        
//在这里添加处理action="xxx"请求的代码
        
//...
        else
        
{
            jspPage
="error.html";
        }

        dispatch(jspPage,request,response);
    }

    
protected void dispatch(String jsp, HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
    
{
        
if(jsp!=null)
        
{
            RequestDispatcher rd
=request.getRequestDispatcher(jsp);
            rd.forward(request,response);
        }

    }

    
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
    
{
            doPost(request, response);
    }

}

注:SessionData为自定义的会话数据对象类


2.利用url改写跟踪会话
在一个公共的web应用上,我们可能遇到一些用户拒绝接收服务器端发送来的cookies,那么此时我们可以用url改写跟踪会话,下面给出它的servlet代码框架

 

import  java.io.IOException;
import  java.util.ArrayList;

import  javax.servlet. * ;
import  javax.servlet.http. * ;
public   class  Controller  extends  HttpServlet
{
    
//在这里声明所用到的模型对象
    
//...
    
    
public void init() throws ServletException 
    
{
        
//在这里添加其他资源的初始化代码(如数据库连接)
        
//...
    }

    
public void destroy()
    
{
        
//在这里添加收回其他资源的代码(如关闭数据库连接)
        
//...
    }

    
//Process the HTTP Get request  
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException 
    
{
        String action
=request.getParameter("action");
        String jspPage
="/index.jsp";
        
if(action==null||action.length()<1)
        
{
            action
="none";
        }

        
if(action.equals("none"))
        
{
            
//创建一个session对象
            HttpSession session = request.getSession(true);
            
            
//将会话数据对象添加到session的属性中
            
//session.setAttribute("xxx", new SessionData());
            
            
//重写url
            String url=response.encodeURL("controller");
            request.setAttribute(
"url_data", url);
        }

        
else if(action.equals("home"))
        
{
            HttpSession session 
= request.getSession(false);
            
if(session!=null)
            
{
                
//获取会话数据对象
                
//SessionData data=(SessionData)session.getAttribute("xxx");
                
                
//在这里添加处理action="home"请求的代码
                
//...
            }

            
else
            
{
                jspPage
="error.html";
            }

        }

        
else if(action.equals("xxx"))
        
{
            HttpSession session 
= request.getSession(false);
            
if(session!=null)
            
{
                SessionData data
=(SessionData)session.getAttribute("xxx");
                
//在这里添加处理action="xxx"请求的代码
                
//...
            }

            
else
            
{
                jspPage
="error.html";
            }

        }

        
        
//在这里添加处理action="其他"请求的代码
        
//...
        else
        
{
            jspPage
="error.html";
        }

        dispatch(jspPage,request,response);
    }

    
protected void dispatch(String jsp, HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
    
{
        
if(jsp!=null)
        
{
            RequestDispatcher rd
=request.getRequestDispatcher(jsp);
            rd.forward(request,response);
        }

    }

    
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException
    
{
            doPost(request, response);
    }

 

在上面的代码中,当第一次请求时(自定义url参数action为none),则为该用户定义一个新的session,此后每次都通过HttpSession session = request.getSession(false)获得该session,如果为null,则此时的处理方法就如同上面没有成功读取cookies中的sessionid一样了。而且,在接收第一次请求时我们还通过代码String url=response.encodeURL("controller");request.setAttribute("url_data", url);改写了url。这样,我们只要在在jsp页面中定义一个作用域为session的变量url,
<c:if test="${empty url}">
 <c:set var="url" value="${requestScope.url_data}" scope="session"/>
</c:if>
此后jsp页面中的每个链接只需写成这样的形式即可${url}?action=xxx&...

下面总结一下这两种方法各自的优点和缺点

cookies跟踪会话
优点:地址栏中的url简洁明了
缺点:会话数据对象所在的hashtable学要自己编写代码来处理回收工作,如一个sesssion结束后相应的会话数据也就无效了,但是我们不知道何时一个session结束,因此只有监视表中的每个对象,当超过一个指定的时间间隔就回收。而且,当用户拒绝使用cookies是该方法就无效了。

url改写跟踪会话
优点:不用自定义hash表结构,可以直接通过session.setAttribute("xxx", new SessionData())来保存会话数据对象,回收也是自动的(事实上它也正式采用了面的机制,因此我们可以设置有效时间间隔,默认为30分钟)

缺点:除默认链接外,地址栏中的url冗长,一般形式为www.xxx.com/controller;jsessionid=3490E0D8F7F0D0SDS7DFDFF?action=xxx&... 

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值