为了在一定时间长度内保存会话中用户产生的数据,Java衍生出了两个机制:Cookie和Session
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。
举个通俗的例子: 我办了理发店会员卡 ,下次带卡来,证明我来过。(在客户端留下一点东西,客户端下次带过来,证明来过了。)
不设置过期时间:则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。 设置了过期时间:浏览器会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
在地址栏再按下回车:
Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
举个通俗的例子: 我办了理发店会员,在店铺笔记本上记录了用户消息,下次来直接报上会员名就可以了。(在服务器端登记你来过。)
只要客户端一旦连接上服务器,服务器就会自动产生Session;一个连接对应一个Session,Session可以在一个会话中传递信息,所有该客户的状态信息都保存在这个Session对象里;由服务器端控制,服务器如果重启了,信息就会丢失!
Session也是一种key-value的属性对,通过getAttribute(String key)和setAttribute(String key,Object value)方法读写客户状态信息。Servlet里通过request.getSession()方法获取该客户的 Session。
例如:
获取Session对象。HttpSession session = request.getSession();设置Session中的属性。session.setAttribute("loginTime", new Date());获得Session中的值。session.getAttribute("loginTime");session保存在服务器端,会一直存在,默认存在时间30分钟;可以通过配置web.xml修改Session的过期时间。 关闭浏览器后, session数据并没有丢失,只是关闭浏览器后,因为cookie保存sessionID,服务器会根据cookie中sessionID获取session;而默认的cookie生命周期为浏览器的缓存,即关掉浏览器之后cookie就失效了,此时sessionID也就没有了。再次访问后,服务器又生成一个新的sessionID,此时request.getSession()通过sessionID获取到的session就不是之前的session了。
Servlet 1:
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; public class TestServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决乱码问题: req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); //Session由服务器自动创建,如何获得Session? //HttpSession 得到的Session对象 HttpSession session = req.getSession(); //得到SessionID,一次会话,一个SessionID; String id = session.getId(); resp.getWriter().print("获得的SessionId"+id+"<br>"); String name = "小明"; //向Session对象中存入一个值; session.setAttribute("name",name); resp.getWriter().print("存入信息成功:"+name); } }Servlet 2:
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; //获得Session存入的值 public class TestServlet2 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决乱码问题: req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;charset=UTF-8"); //获得Session对象 HttpSession session = req.getSession(); System.out.println("得到的SessionID:"+session.getId()); //获得Session对象中的信息 String name = (String) session.getAttribute("name"); resp.getWriter().print("得到的Session存入的信息:"+name); } }配置web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>Session1</servlet-name> <servlet-class>com.fox.servlet.TestServlet</servlet-class> </servlet> <servlet> <servlet-name>Session2</servlet-name> <servlet-class>com.fox.servlet.TestServlet2</servlet-class> </servlet> <!-- ======================================================--> <servlet-mapping> <servlet-name>Session1</servlet-name> <url-pattern>/s1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Session2</servlet-name> <url-pattern>/s2</url-pattern> </servlet-mapping> </web-app>启动Tomcat访问:
Session对象默认有效时间为30分钟,30分钟后它会自动销毁。 也可以使用以下两种方式注销Session对象:
在上文案例中Servlet 2 最后一行添加session.invalidate();,则在地址栏再按下回车,Session对象已被注销,显示如下:
session-config可以设置会话自动过期的时间,以分钟为单位。
<session-config> <session-timeout>1</session-timeout> </session-config>