徐岸 兰全祥
摘要:在Web应用中会话跟踪技术被用于保持客户端访问服务器时连续的状态的常用技术.正是由于会话跟踪技术的出现使得Web应用开发变得更加便利,并且提高了网站性能.本文将围绕JavaWeb中的会话跟踪技术展开及其域对象分析与讨论,探讨了会话跟踪技术的背景、工作机制、相关应用以及对它们的比较.
关键词:会话跟踪技术;Cookie Session Web应用
中图分类号:TP393.09 文献标识码:A 文章编号:1673-260X(2020)02-0057-03
1 引言
传统的HTTP(HyperText Transfer Protocol)协议本身是无状态[1],即在Web应用中多个客户端访问服务器端时,服务器端并不能区分各个客服端状态信息.这种无状态的缺陷阻碍了Web应用的发展.
为了解决HTTP无状态的缺陷,Netscape公司推出了一项HTTP的状态管理机制:Cookie[1].服务器使用Cookie就能跟踪每个客户端的访问.但每次客户端访问都会传回这些Cookie,当Cookie数量很多时,这样无疑地增加了服务器的压力.Session的出现就解决了这个问题.Session技术是基于Cookie技术的服务器端数据存储技术.JSP(Java Server Pages)为了存储客户端信息,也提出了Request Scope和Context Scope等技术.正是利用它们不同的特性,简化了服务器端的程序设计、增加了Web应用开发的便利性,并且提高了网站性能.
在一个客户端中打开浏览器访问某个网站开始,直到关闭这个浏览器的整个过程,称为一次会话.会话技术就是记录一次会话中客户端的状态与数据的技术.在Web应用开发中通常使用Cookie、Session、Request Scope、Context Scope等会话技术来存储客户端信息.
2 技术分析
2.1 Cookie-
当客户端第一次访问服务器时,服务器将用户相关信息以Cookie的形式传输给客户端[2].客户端浏览器一旦接收了服务器发出的Cookie信息,就会将它存储在浏览器缓冲区,即将数据存储在客户端中,当浏览器后续访问该服务器时,都会在请求消息中将用户相关信息以Cookie的形式发送给服务器,从而使得服务器可以分辨是哪个客户端发送的请求(如图1所示).
在Tomcat服务器中真正意义上创建Cookie是在org.apache.catalina.connector.Response类,通过调用generateCookieString方法将Cookie对象构造成一个遵循Cookie语法规则的字符串,并将这个字符串添加到MimeHears中,从而构建HTTP响应头返回至客户端.在Servlet中提供了setPath(String path)、setMaxAge(int expiry)等方法來设置HTTP响应头Set-Cookie字段的属性项.其中setPath(String path)是设置Cookie被允许访问的路径,如果不设置携带路径,那么该Cookie信息会在访问产生该Cookie的Web资源所在的路径都携带cookie信息.在Servlet中使用javax.servlet.http.HttpServletRequest类中的getCookies()方法获得一个Cookie的对象数组;使用javax.servlet.http.HttpServletResponse类中的addCookie(Cookie cookie)方法向客户端发送Cookie
2.2 Session
Session技术是基于Cookie技术的服务器端数据存储技术,即Session需要借助于Cookie所存储的客户唯一性标识JSESSIONID,即从客户端传输一个NAME为JSESSIONID的Cookie给服务器,而这个JSESSIONID是客户端第一次访问服务器时所生成.在一次会话中客户端只要传回JSESSIONID给服务器,Tomact服务器就会选择与之对应的Session对象为其服务[5].(如图2所示)
当JSESSIONID传入Tomact服务器中时,Tomact服务器中会将传入的JSESSIONID解析为Session ID.当使用request.getSession()获得HttpSession对象时,服务器就是利用Session ID判断在Session容器中是否存在与之对应的HttpSession对象.如果有就返回该HttpSession对象;如果没有,服务器就会创建一个新的HttpSession对象,并将这个对象添加到org.apache.catalina.Manager类的Session容器中.其中Manager类的功能是负责管理所有Session的生命周期、服务器关闭时Session将被序列化到磁盘、Session过期回收等.
2.2 Request Scope
Request是在Servlet方法调用前由Tomact服务器创建,Tomact服务器接到请求后,首先会创建org.apache.coyote.Request对象,Tomact服务器经过对此对象解析后会交给用户线程去处理这个请求,同时会创建org.apache.connector.Request对象,这个对象将贯穿Servlet容器直至传给Servlet.正是由于这样的特性,Requese中存储的数据可以在一次请求链中多次获取,直至请求结束.
2.4 Context Scope
Context Scope的数据在Tomact服务器中是存放在ServletContext中,而在Servlet中获得的ServletContext对象实际是ApplicationContextFacade对象,ApplicationContextFacade和ServletContext使用的是门面设计模式,它们可以在Context容器中获取属于他们的数据,并且对数据起到封装作用.在服务器中ServletContext是在Tomact服务器启动时就会被服务器创建,直至服务器关闭或该Web应用被移除.ServletContext中的数据被所有客户端共享.
3 应用
3.1 通过Cookie保存用户信息
当用户在其所信任的客户端登录Web应用时,在服务器端对该用户的登录信息进行处理.那么该用户在后续访问该网站可直接以登录状态直接访问.实现的方法是将用户登录信息保存在Cookie中,并控制Cookie的有效期,下次访问网站时服务器验证Cookie中的用户信息即可.
但是Cookie是可以在浏览器明文查看的,Web应用中通常情况下,不会把密码等重要的用户信息保存到Cookie中.在上述条件下的实现方式:在服务器中将用户的账号通过MD5算法进行加密,将加密后的账号和用户账号一起保存到Cookie中(Java实现代码如下).用户在后续登录时验证账号的加密规则是否正确即可.
String autoLogin = request.getParameter("autoLogin");
if ("true".equals(autoLogin)) {
String account = request.getParameter("account");
String ssid = MD5Utils.MD5(account);
Cookie accountCookie = new Cookie("userID", account);
accountCookie.setMaxAge(30*60);
Cookie ssidCookie = new Cookie("ssid", ssid);
ssidCookie.setMaxAge(30*60);
response.addCookie(accountCookie);
response.addCookie(ssidCookie);
response.sendRedirect(request.getRequestURI() + "?" +System.currentTimeMillis());
}
3.2 利用Session防止表单重复提交
在Web应用中很多时候存在用户重复提交表单的情况,如由于用户操作不当多次提交表单;用户网速过慢,不断重复刷新提交表单;恶意用户通过相关程序恶意重复提交表单等.上述非常规操作都会导致表单的重复提交.表单的重复提交可能会造成服务器端的数据重复,增加服务器的压力,影响服务器的性能,甚至严重的话,可能会对服务器造成宕机的情况,因此Web应用中防止表单重复提交的技术显得尤为重要.
利用Session防止表单重复提交,需要在该表单中增加一个隐藏表单项.如下面JSP代码所示: