JSP/Servlet会话管理机制
(一)知识概念
在Web服务器端编程中,会话状态管理是一个经常必须考虑的重要问题。根据设计,HTTP是一种无状态的协议。它意味着Web应用并不了解有关同一用户以前请求的信息。
JSP有四个会话机制。Request,Session,Cookie,Application分别可以存储不同范围的值。
l Request
l Session
l Cookie
l Application
1.Request
(1)request.getParameter() 和request.getAttribute() 区别
1. request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据,request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
2. request.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。
(2)request.getAttribute()与request.setAttribute()
request.getAttribute("nameOfObj")可得到JSP页面一表单中控件的Value。其实表单控件中的Object的 name与value是存放在一个哈希表中的,所以在这里给出Object的name会到哈希表中找出对应它的value。
而不同页面间传值使用request.setAttribute(position, nameOfObj)时,只会从a.JSP到b.JSP一次传递,之后这个request就会失去它的作用范围,再传就要再设一个 request.setAttribute()。而使用session.setAttribute()会在一个过程中始终保有这个值。
(3)request.getParameter() 和request.getParameterValues()
request.getParameterValues(String name)返回数组String[],用于获得如checkbox类(名字相同,但值有多个)的数据。
request.getParameter(String name)返回String,用于获得相应名的数据,如果有重复的名,则返回第一个的值。
(4)其它
JavaScript与JSP中不能相互传值,因为JavaScript运行在客户端,而JSP运行在服务器端。若想使它们之间可以相互传递参数,可以在JSP中设置一个hidden控件,用它的value结合上面所说的用法来传递所需的数值。
2.session、cookie、application
session、cookie、application是JSP中 的重要对象,这些对象和程序语言中的全局变量有些相似。在使用程序语言设计软件程序时,不同的程序文件之间需要传递或共享某些数据,这就需要全局变量(也 叫公用变量)。在一个站点内,有众多的动态网页,每个网页就相当于一个独立的程序文件,他们之间的数据传递和数据共享就依赖于session等这些对象。但他们的应用不同于程序语言。存在的位置和使用的方法都和网络环境有着密切联系。这些对象一但被创建,session、application存在于JSP服务器上,cookie存在于客户机上。session、cookie在使用时,能区分不同的用户,会为不同IP地址的用户,创建单独的session或cookie。而application应用时是针对所有用户的。下图是表示他们之间区别和关系的示意图:
这些对象在使用时,先要创建(定义),然后将需要的数据写入。到了其他的动态网页中,就可以提取。设定或改变对象的属性参数,能够能够改变他存在的形式和寿命,还可以在不需要时,将其删除。
(二)应用举例
1.客户端向服务器
(1)get方式
<a href="xx.jsp?id=<%=id%>"></a>
<a href="xx.jsp?id=2"></a>
<script language='javascript'>
var val = document.getElementById('varSort').value;
window.location.href = "index.jsp?param=" + val;
</script>
(2)post方式
<form action="xx.jsp?act=3" method="post" enctype="multipart/form-data" name="upfile" id="upfile">
<input type="hidden" name="id" value="<%=id%>">
<input type="text" name="root">
</form>
2.服务器端
response.sendRedirect做转向的原理,它其实是向浏览器发送一个特殊的Header,然后由浏览器来做转向,转到指定的页面,所以用sendRedirect时,浏览器的地址栏上可以看到地址的变化。
用<jsp:forward page=""/>则不同,它是直接在server做的,浏览器并不知道,也不和浏览器打交道,这从浏览器的地址并不变化可以看出。
(1)跳转之后 地址栏变为xx.jsp【客户端跳转】
response.setHeader("refresh", "5", "xx.jsp");
response.sendRedirect("xx.jsp?=" + id);
(2)跳转以后地址栏不变【服务器端跳转】
<jsp:forward page="xx.jsp">
<jsp:param name="g" value="<%=name%>"/>
</jsp:forward>
<jsp:include flush="true" page="xx.jsp">
<jsp:param name="t" value="<%=request.getParameter("id")>">
</jsp>
(3)session
session.setAttrubute("name", name)
l session是在多个页面之中有效,而不是只在两个页面中有效,直到关闭浏览器才失效。
l session销毁的三个条件
n 服务器停
n 设置的时间到
n 手动关闭
l 打开多个浏览器和打开多个标签页之间的区别。
(4)Cookie
写入cookie
Cookie user=new Cookie("user", username);
Cookie pass=new Cookie("pass", password);
response.addCookie(user);
response.addCookie(pass);
从cookie中提取数据
Cookie[] allcookie = request.getCookies();
name2=allcookie[0].getValue();
mima2=allcookie[1].getValue();
(5)application
数据写入application
application.setAttribute("dirimg", myimg);
从application中读取数据
tp = (String)application.getAttribute("dirimg");
3.javaBean
通过表单提交过来的值,经过Bean自动的将字符串处理为相应的数据类型,然后自动的与javaBean中的属性相同的名称进行匹配。
<jsp:useBean id="testBean" class="swing.useBean" scope="session"/>
<jsp:setProperty name="testBean" property="*"/>
</jsp:useBean>
bookName:<%=testBean.getBookName()%>
bookCompany:<%=testBean.getBookCompany()%>
4.jsp与javascript中文cookie交互
jsp 写入中文Cookie
<%@ page contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%>
<%@ page import="java.net.*"%>
<%
String usr = "中文cookie测试";
Cookie cookie = new Cookie("usr", URLEncoder.encode(usr, "UTF-8"));
cookie.setMaxAge(31536000);
cookie.setPath("/");
response.addCookie(cookie);
%>
javascript 读取中文cookie
<script language="javascript">
function readCnCookie(name) {
var strReturn = null;
var tmp, reg=new RegExp("(^| )" + name + "=\"*([^;|^\"]*)(|;|$)", "gi");
if(tmp=reg.exec(document.cookie))
strReturn = decodeURIComponent(tmp[2]);
return strReturn;
}
alert(readCnCookie("usr"));
</script>
同样, 不管有什么服务端语言, 写入cookie 时 把中文使用 URLEncode 就可以和js交互了
在其它的语言环境下实现 new Cookie("usr",URLEncoder.encode(usr,"UTF-8"))方法:
l ASP:Server.URLEncode(string);
l PHP:urlencode($string);
n 如果编码不对, 记得用 iconv 转换一下
n 例: gb2312转utf-8 iconv("GB2312", "UTF-8", $string);
l ASP.NET:
n System.Web.HttpUtility.UrlEncode(string);
n System.Web.HttpUtility.UrlEncode(string, "UTF-8");
5.理解HTTP session原理及应用
全文见:http://www.cnblogs.com/athrun/archive/2008/11/26/1341442.html
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为 session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个 session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个 session id将被在本次响应中返回给客户端保存。
(1)Session与cookie
保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是 JSESSIONID。
(2)Session与URL
由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
(3)session在服务端的解析
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。
为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。