为了在一定时间长度内保存会话中用户产生的数据,Java衍生出了两个机制:Cookie和Session
Cookie 是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器之后向同一服务器再次发起请求时被携带上,用于告知服务端两个请求是否来自同一浏览器。
举个通俗的例子:
我办了理发店会员卡 ,下次带卡来,证明我来过。(在客户端留下一点东西,客户端下次带过来,证明来过了。)
Cookie cookie = new Cookie(String name,String value);
Response.addCookie(Cookie);
Cookie[] cookies = Request.getCookie();
//判断cookies是否为空,然后遍历即可
Cookie.getName();
Cookie.getValue();
不设置过期时间:则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。
设置了过期时间:浏览器会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestServlet extends HttpServlet {
boolean flag=false;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决乱码问题:
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//检查请求的人是否带了cookie
Cookie[] cookies=request.getCookies();
System.out.println("cookie:"+cookies);
if(flag) {
//判断你是不是第一次来
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals("lastLoginTime")) {
response.getWriter().println("你上次来的时间为:" + cookie.getValue());
System.out.println("刷新了cookie");
}
}
}
else{
response.getWriter().println("你是第一次来");
System.out.println("给该用户一个cookie");
}
//建立一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//把这个cookie发给客户端
response.addCookie(cookie);
flag=true;
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
<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>Demo01servlet-name>
<servlet-class>com.fox.servlet.TestServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>Demo01servlet-name>
<url-pattern>/curl-pattern>
servlet-mapping>
web-app>
Session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。
举个通俗的例子:
我办了理发店会员,在店铺笔记本上记录了用户消息,下次来直接报上会员名就可以了。(在服务器端登记你来过。)
只要客户端一旦连接上服务器,服务器就会自动产生Session;一个连接对应一个Session,Session可以在一个会话中传递信息,所有该客户的状态信息都保存在这个Session对象里;由服务器端控制,服务器如果重启了,信息就会丢失!
Session也是一种key-value的属性对,通过getAttribute(String key)
和setAttribute(String key,Object value)
方法读写客户状态信息。Servlet里通过request.getSession()
方法获取该客户的 Session。
例如:
HttpSession session = request.getSession();
session.setAttribute("loginTime", new Date());
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+"
");
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:
<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>Session1servlet-name>
<servlet-class>com.fox.servlet.TestServletservlet-class>
servlet>
<servlet>
<servlet-name>Session2servlet-name>
<servlet-class>com.fox.servlet.TestServlet2servlet-class>
servlet>
<servlet-mapping>
<servlet-name>Session1servlet-name>
<url-pattern>/s1url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>Session2servlet-name>
<url-pattern>/s2url-pattern>
servlet-mapping>
web-app>
Session对象默认有效时间为30分钟,30分钟后它会自动销毁。
也可以使用以下两种方式注销Session对象:
在上文案例中Servlet 2 最后一行添加session.invalidate();
,则在地址栏再按下回车,Session对象已被注销,显示如下:
session-config
可以设置会话自动过期的时间,以分钟为单位。
<session-config>
<session-timeout>1session-timeout>
session-config>