Cookie和Session

  什么是会话,在日常生活中我们从接电话到挂断电话的过程,就是一次会话的过程。在Web应用中,也会产生类似打电话的过程,它指的是客户端(浏览器)和web服务器之间连续发生的一系列请求和响应的过程。

为了保存会话过程中产生的数据,Servlet技术中,提供了两个用于保存会话数据的对象,CookieSession

  什么是Cookie,当用户通过浏览器访问服务器时,服务器就会给用户浏览器返回一些信息,这些信息就会保存在Cookie中,这样当用户再次访问服务器时,就会在请求头中将Cookie发送给服务器,方便服务器对浏览器做出正确的响应。

  服务器在给客户端发送Cookie时,会在Http响应头字段中中添加Set-Cookie响应头字段:Set-Cookie:user=test;Path=/;其中,userCookie的名称,test是它的值,Paht表示Cookie的属性,Cookie都是以键值对的方式存放的,其属性可以有多个,以;隔开。一旦用户浏览器接收了服务器发送的Cookie信息,那么它会保存在浏览器的缓存区中,后续的访问服务器中的,都会带上Cookie访问。

Constructor Summary
Cookie(String name,String value)
          Constructs a cookie with a specified name and value.

一旦创建了,name是不能更改的,而value是可以修改的

Cookie操作的主要方法

Method Summary
 Objectclone()
          Overrides the standard java.lang.Object.clone method to return a copy of this cookie.
覆写Object类的clone方法,拷贝一份新的Cookie对象
 StringgetComment()
          Returns the comment describing the purpose of this cookie, or null if the cookie has no comment.
返回该Cookie的描述
 StringgetDomain()
          Returns the domain name set for this cookie.
返回Cookie的有效域
 intgetMaxAge()
          Returns the maximum age of the cookie, specified in seconds, By default,-1 indicating the cookie will persist until browser shutdown.
返回Cookie的生存期,如果为-1,表示浏览器关闭,则立即清除
 StringgetName()
          Returns the name of the cookie.
返回Cookie的名称
 StringgetPath()
          Returns the path on the server to which the browser returns this cookie.
返回cookie的有效目录路径
 booleangetSecure()
          Returns true if the browser is sending cookies only over a secure protocol, orfalse if the browser can send cookies using any protocol.
如果该Cookie采用的是安全协议,则返回true,否则返回false
 StringgetValue()
          Returns the value of the cookie.
返回Cookie的值
 intgetVersion()
          Returns the version of the protocol this cookie complies with.
返回Cookie采用的协议版本
 voidsetComment(String purpose)
          Specifies a comment that describes a cookie's purpose.
设置该Cookie的描述
 voidsetDomain(String pattern)
          Specifies the domain within which this cookie should be presented.
设置Cookie的有效域
 voidsetMaxAge(int expiry)
          Sets the maximum age of the cookie in seconds.
设置最大生存期,单位秒
 voidsetPath(String uri)
          Specifies a path for the cookie to which the client should return the cookie.
设置有效路径
 voidsetSecure(boolean flag)
          Indicates to the browser whether the cookie should only be sent using a secure protocol, such as HTTPS or SSL.
设置cookie的传输协议
 voidsetValue(String newValue)
          Assigns a new value to a cookie after the cookie is created.
设置cookie的值
 voidsetVersion(int v)
          Sets the version of the cookie protocol this cookie complies with.
设置Cookie的协议版本

1、setMaxAge(int expiry)和getMaxAge()方法

设置和返回Cookie在浏览器中保存的有效秒数,为正整数,则从当前时间算起,没有超过该秒数之前,Cookie会一直保留在浏览器本地缓存中,为负数,则会在浏览器关闭的时候清除该Cookie,如果设置为0,则通知浏览器立刻删除Cookie,默认情况,Max-Age属性值为-1。

2、setPath(String uri)和getPath()方法

上面两个方法是针对Cookie的Path属性的。如果创建Cookie对象时没有设置path属性,表示该Cookie对当前访问路径下的所有目录和子目录都有效,如果想让某个Cookie项对站点的所有目录下的访问路径都有效,则设置为 “/”。

3、setDomain(String pattern)和getDomain()方法

上面两个方法是针对Cookie的Domain属性的,指定浏览器访问的域。当设置Domain属性时,其值必须以"."开头,如Domain=.winlu.cn 。默认情况下,demoain属性的值为当前的主机名,浏览器在访问当前主机下的资源时,都会将Cookie信息返回给服务器。Domain属性是不区分大小写的。


 Cookie案例:显示用户上一次访问的时间

package cookie;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CookieDemo01 extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//将最后访问时间存放在Cookie中
		Date lastAccessTime = null;
		//遍历Cookies
		Cookie[] cookies = request.getCookies();
		if(cookies != null){
			for (Cookie cookie : cookies) {
				String cookieName = cookie.getName();
				if("lastAccessTime".equals(cookieName)){
					try {
						lastAccessTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(cookie.getValue());
					} catch (ParseException e) {
						e.printStackTrace();
					} 
					break;
				}
			}
		}
		
		if(lastAccessTime != null){
			System.out.println("上一次访问服务器的时间:"+lastAccessTime);
		}else{
			System.out.println("第一次访问服务器");
		}
		Cookie cookie = new Cookie("lastAccessTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		response.addCookie(cookie);
	}

}

Cookie技术可以将用户的信息保存在各自的浏览器中,并且可以在多次请求下实现数据共享,但是如果传递过多,会增加服务器端处理的难度,这是就可以使用session来实现将会话数据保存到服务器的端。

什么是session呢?当浏览器访问web服务器时,servlet容器会创建一个Session对象和ID属性,当客户端后续访问服务器时,只需要将标识号传递给服务器,服务器就可以判断出请求是哪个客户端发送的,从而选择对应的session对象为其服务。由于客户端需要接收、记录和回送Session对象的ID,因此,通常情况下,session是借助Cookie技术来实现的ID属性的传递的。

session主要的操作方法

Method Summary
 ObjectgetAttribute(String name)
          Returns the object bound with the specified name in this session, or null if no object is bound under the name.
返回根据名称绑定在httpSession中的Object对象
 EnumerationgetAttributeNames()
          Returns an Enumeration of String objects containing the names of all the objects bound to this session.
返回httpSession中所有绑定对象的名称集合
 longgetCreationTime()
          Returns the time when this session was created, measured in milliseconds since midnight January 1, 1970 GMT.
返回Httpsession的创建时间,从1971年1月1日算起的毫秒数
 StringgetId()
          Returns a string containing the unique identifier assigned to this session.
返回与当前httpSession对象关联的会话标识
 longgetLastAccessedTime()
          Returns the last time the client sent a request associated with this session, as the number of milliseconds since midnight January 1, 1970 GMT, and marked by the time the container received the request.
返回客户端最后一次发送与session相关的请求时间
 intgetMaxInactiveInterval()
          Returns the maximum time interval, in seconds, that the servlet container will keep this session open between client accesses.
返回会话的最大持续时间
 ServletContextgetServletContext()
          Returns the ServletContext to which this session belongs.
返回该session所属的web应用对象,即代表当前web应用的ServletContext对象
 HttpSessionContextgetSessionContext()
          Deprecated. As of Version 2.1, this method is deprecated and has no replacement. It will be removed in a future version of the Java Servlet API.
(过时了)
 ObjectgetValue(String name)
          Deprecated. As of Version 2.2, this method is replaced bygetAttribute(java.lang.String).
(过时了)
 String[]getValueNames()
          Deprecated. As of Version 2.2, this method is replaced bygetAttributeNames()
(过时了)
 voidinvalidate()
          Invalidates this session then unbinds any objects bound to it.
强制使session对象失效
 booleanisNew()
          Returns true if the client does not yet know about the session or if the client chooses not to join the session.
判断当前的session对象是不是新创建的
 voidputValue(String name,Object value)
          Deprecated. As of Version 2.2, this method is replaced bysetAttribute(java.lang.String, java.lang.Object)
(过时了)
 voidremoveAttribute(String name)
          Removes the object bound with the specified name from this session.
用于从当前的httpSession对象删除指定名称的属性
 voidremoveValue(String name)
          Deprecated. As of Version 2.2, this method is replaced byremoveAttribute(java.lang.String)
(过时了)
 voidsetAttribute(String name,Object value)
          Binds an object to this session, using the name specified.
指定名称绑定对象到httpSession中
 voidsetMaxInactiveInterval(int interval)
          Specifies the time, in seconds, between client requests before the servlet container will invalidate this session.
设置Session的最大生存期
     

Session是与每个请求消息紧密相关的,因此HttpServletRequest定义了用于获取Session对象的getSessoin方法,有两种重载方式:

	public  HttpSession getSession(boolean create);//true ,则在相关的httpsession对象不存在的时候返回新的Session对象,否则不创建,返回null
	public HttpSession getSession();//相当于第一个方法的create为true情况

session超时管理

当客户端第一次访问某个能开启会话功能的资源时,web服务器就会创建一个与该客户端对应的HttpSession对象。在HTTP中,web服务器是无法判断当前客户端浏览器是否还会继续访问,因此也无法检测客户端浏览器是否已经关闭,所以客户端已经离开或者关闭了浏览器,web服务器依然保存着与之对应的HttpSession对象,随着时间的推移,这些不再使用的HttpSession对象将会在web服务器中越积越多,从 而耗尽服务器的内存。

为解决上述问题,web服务器采用了Session超时限制的办法来判断客户端是否还继续访问。在一定时间内,如果某个客户端一直没有请求访问,那么web服务器就会认为客户端请求已经结束,并且销毁服务器内存中的session对象所占用的空间。如果浏览器在此访问,web服务器就会重新创建一个httpSession对象,并为其分配一个新的ID属性。在会话过程中,会话有效时间可以在web.xml文件中配置

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

如果将时间设置为0,则表示永远不超时,那么就需要用户通过invalidate()使会话失效或直接删除对应的session对象,从而释放内存。


Session案例:实现用户登陆

 


IndexServlet

package session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class IndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

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

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//判断用户是否已经登陆过了,没有则跳转到登陆页面
	    //从session中获取用户信息
		User user = (User) request.getSession().getAttribute("user");
		if(user == null){//没有登陆过
			//重定向到登陆页面
			response.sendRedirect(request.getContextPath()+"/index.jsp");
		}else{ //登陆过了
			//获取当前的SessionID
			String sessionId = request.getSession().getId();
			//创建一个Cookie
			Cookie cookie = new Cookie("JSESSINOID", sessionId);
			cookie.setPath("/");
			cookie.setMaxAge(60*30);
			response.addCookie(cookie);
			response.sendRedirect(request.getContextPath()+"/index.jsp");
		}
	}

}

LoginServelt
package session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		//这里默认 用户名是  吴渣渣   密码 123
		if("吴渣渣".equals(username) && "123".equals(password)){ //登陆成功
			User user = new User();
			user.setUsername(username);
			user.setPassord(password);
			request.getSession().setAttribute("user", user);
			response.sendRedirect(request.getContextPath()+"/IndexServlet");
		}else{ //登陆失败
			request.getRequestDispatcher("/login.jsp").forward(request, response);
		}
	}
}

LogoutServlet
package session;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogoutServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//将session中的user对象移除
		request.getSession().removeAttribute("user");
		response.sendRedirect(request.getContextPath()+"/IndexServlet");
	}

}

index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>首页</h1>
	<c:if test="${user.username != null}">
		欢迎你,${user.username} <a href="<%=request.getContextPath() %>/LogoutServlet">退出登陆</a>
	</c:if>
	<c:if test="${user.username == null}">
		未登录,<a href="<%=request.getContextPath() %>/LoginServlet">点击登陆</a>
	</c:if>
</body>
</html>

login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="/Blog_demo01/LoginServlet" method="post" >
		<span style="color: red">${error }</span><br/>
	   	用户名:<input type="text" name="username" /><br/>
    	密码:    <input type="text" name="password" /><br/>
    	<input type="submit" value="登陆" />
	</form>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值