HTTP 状态管理

HTTP是无状态协议,为了解决记录通信过程中的状态数据的需求可以使用Cookie机制或者Session机制。

状态管理:将浏览器与web服务器之间多次交互所涉及的数据保存下来

保存方式:保存在客户端(Cookie)/保存在服务器端(Session)


(1)Cookie

1)Cookie:浏览器在访问服务器时,服务器会将少量的数据(大约4K左右)以set-cookie消息头的方式发送给浏览器,浏览器会将这些数据保存下来(内存或硬盘)。浏览器再次访问服务器时,会将之前保存的这些数据以cookie消息头的方式发送给服务器。

2)创建Cookie

step1 创建一个Cookie对象

Cookie c = new Cookie(String name, String value);

step2 添加到response对象

response.addCookie(c);

3)查询Cookie

Cookie[] request.getCookies(); //该方法有可能返回null

String cookie.getName();

String cookie.getValue();

4)编码问题

cookie只能保存ascii字符,如果出现非ascii字符,需要将其转换成ascii字符的表示形式。可以使用

编码:String URLEncoder.encode(String str, String enc)

解码:String URLDecoder.decode(String str, String enc)

5)生存时间

cookie.setMaxAge(int seconds);

*当seconds > 0时,浏览器会将cookie保存在硬盘上,超过指定时间删除cookie

seconds < 0时,浏览器会将cookie保存在内存中,只要浏览器关闭,cookie就被删除

seconds = 0时,浏览器会立即删除cookie

6)删除一个cookie

Cookie c = new Cookie("somecookie", "");

c.setMaxAge(0);

response.addCookie(c);

7)cookie的路径问题

浏览器在访问服务器的时候,并不会将所有的cookie全部发送给服务器,而是比较服务器的地址与cookie的地址是否匹配(要访问的服务器的地址是cookie地址或者是cookie地址的子路径),只有符合要求的cookie才会发送。

在默认情况下,cookie的路径(cookie地址)等于添加该cookie的组件的路径。

比如:/WebDemo/jsp01/addCookie.jsp添加了一个cookie,则该cookie的路径为/WebDemo/jsp01

*通过调用cookie.setPath("/appname")可以设置cookie地址

8)一般情况下添加一个cookie的步骤:

Cookie cookie = new Cookie("username", URLEncoder.encode("张三", "utf-8");

cookie.setMaxAge(1000);

cookie.setPath("/WebDemo");

request.addCookie(c);

8)cookie的缺点:

a. 浏览器可以禁止

b. 不安全

c. cookie能够保存的数据大小有限制,只能保存少量的数据(4k)

d. cookie的个数也有限制,大约300个

CookieUtil:

public class CookieUtil {
	
	public static int age = 3600 * 24;

	public static void addCookie(String name, String value, int age, 
			HttpServletRequest request, HttpServletResponse response) 
			throws UnsupportedEncodingException {
		Cookie c = new Cookie(name, URLEncoder.encode(value, "utf-8"));
		c.setMaxAge(age);
		c.setPath(request.getContextPath());
		response.addCookie(c);
	}
	
	public static void addCookie(String name, String value, 
			HttpServletRequest request, HttpServletResponse response) 
			throws UnsupportedEncodingException {
		addCookie(name, value, age, request, response);
	}
	
	public static String findCookie(String name, HttpServletRequest request) 
		throws UnsupportedEncodingException {
		String value = null;
		Cookie[] cookies = request.getCookies();
		if(cookies != null) {
			for(int i = 0; i < cookies.length; i++) {
				Cookie cur = cookies[i];
				if(cur.getName().equals(name)) {
					value = URLDecoder.decode(cur.getValue(), "utf-8");
				}
			}
		}
		return value;
	}
	
	public static void delete(String name, HttpServletResponse response) {
		Cookie c = new Cookie(name, "");
		c.setMaxAge(0);
		response.addCookie(c);
	}
	
}


(2)Session

1)什么是session

当浏览器访问服务器时,服务器会创建一个对象(一般称之为session对象,该对象有一个sessionId,是唯一的),然后将这个sessionId发送给浏览器(默认情况下使用cookie机制发送)。浏览器会将sessionId保存下来,当浏览器再次访问服务器时会将seesionId发送给服务器。服务器依据sessionId就可以找到之前创建好的session对象。

2)获得一个session对象

a. HttpSession s1 = request.getSession(boolean flag);

当flag = true时,

服务器检查请求当中是否有sessionId,如果没有则创建一个session对象。如果有sessionId,会依据sessionId查找对应的session对象,如果找到了则返回;如果找不到(比如session超时,服务器已经将之前创建的session对象删除),则创建一个新的session对象。

当flag = false时,

服务器检查请求当中是否有sessionId,如果没有则返回null。如果有sessionId,会依据sessionId查找对应的session对象,如果找到了则返回;如果找不到则返回null。

b. HttpSession s2 = request.getSession();

等价于request.getSession(true);

3)session的几个常用方法

String session.getId();

session.setAttribute(String name, Object obj);

Object session.getAttribute(String name);

session.removeAttribute(String name);

4)session超时

容器会将空闲时间过长的session对象从内存里删除掉(为了节省内存空间)。

大部分容器的缺省时间是30分钟。

可以修改服务器缺省的超时时间限制:

比如tomcat可以修改$CATALINA_HOME/conf/web.xml中

<session-config>

    <session-timeout>30</session-timeout>

</session-config>

修改后需要重启服务器

也可以修改某个应用的web.xml

另外,session.setMaxInactiveInterval(int seconds);

5)session删除

session.invalidate();

6)案例

a. session验证

step1 在登录成功之后,将一些数据绑定到session对象上

比如: session.setAttribute("user", user);

step2 对于需要保护的资源(只有登录成功以后才能访问的地址),添加session验证代码。

比如:

Object obj = session.getAttribute("user");

if(obj == null) {

    // 没有登录

    response.sendRedirect("login.jsp");

}

b. 验证码

c. 购物车

7)当用户禁止cookie后,如何使用session

可以使用url重写机制

url重写:在访问某个组件时,不直接使用其地址,而是使用包含了服务器生成的sessionId的地址。

链接地址、表单提交地址使用response.encodeURL(String url)进行处理。

重定向地址使用response.encodeRedirectURL(String url)进行处理。

8)session的优缺点

跟cookie比,session相对来讲会更安全,保存的数据大小从理论上没有限制,保存的数据类型更丰富。

session是一种服务器端状态管理技术,会将所有的状态保存在服务器端,所以服务器的数据压力会更大(服务器可以将session中的数据临时保存到数据库或者硬盘上)。

 

*有时候需要同时使用session和cookie一起来解决比较复杂的状态管理问题


你可能感兴趣的:(HTTP 状态管理)