Session
在Web开发中,服务器可以为每个用户浏览器创建一个会话对象(Session对象),注意:一个浏览器独占一个Session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
Session原理
用户打开浏览器访问Servlet时,在该Servelt调用如下代码,即可创建Session。
HttpSession session = request.getSession();
服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。
Session创建与销毁
Session创建
在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的,随后同一个客户端再次调用会使用同一个Session。
可以使用request.getSession(false)来保证不创建新的Session;相反,request.getSession(true)方法每次都创建新的Session。
Session销毁
在Java中,默认session在30分钟之内未被使用,服务器就会将session销毁,不管用户浏览器此时有没有关闭。即便用户关闭了浏览器,结束了当前会话,session也不会立即销毁,直到默认时效内session未被使用。
可以通过Web应用的配置文件web.xml,配置session的有效时间,如这里设置为10分钟:
10
手动销毁session,则调用session对象的方法,如:
session.invalidate();
Session实战
下面完成一个利用session完成用户登录的简单例子。
创建一个Java Web项目,编写登陆页面login.html。
登录
编写处理登录请求的页面LoginServlet.java。
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取用户, 因为是示例省略了校验的过程
String username = request.getParameter("username");
String password = request.getParameter("password");
// 将用户名存入session
HttpSession session = request.getSession();
session.setAttribute("username", username);
response.sendRedirect(request.getContextPath() + "/hello.jsp");
return;
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
登陆成功后的跳转页面hello.jsp。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
欢迎页面
欢迎您,${username}! 退出登录
退出登录LogoutServlet.java。
public class LogoutServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if(session == null) {
response.sendRedirect(request.getContextPath() + "hello.jsp");
return;
}
session.removeAttribute("user");
response.sendRedirect(request.getContextPath() + "/login.html");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
在web.xml中配置servlet。
LoginServlet
com.wyk.servletdemo.web.LoginServlet
LogoutServlet
com.wyk.servletdemo.web.LogoutServlet
LoginServlet
/LoginServlet
LogoutServlet
/LogoutServlet
运行程序,访问 http://localhost:8080/servletdemo/login.html ,随便输入一个用户名和密码。
点击登录,跳转到欢迎界面。可以看到session传递过来的用户名显示在了界面。
通过退出登录将用户名从session中移除。
解决浏览器关闭后丢失Session ID的问题
根据Session实现原理,我们可以知道,在默认情况下,当我们关闭浏览器后保存Session ID的Cookie也将被销毁,即我们再次打开浏览器发送相同请求,获得到的Session对象也不再与之前相同。
需要注意的是,关闭浏览器后服务器存储的Session不一定就被销毁了,服务器存储的Session是在一定时间内未被操作,服务器才会将其销毁。这里关闭浏览器之后无法再使用上次Session的原因,在于我们丢失了Session ID(保存Cookie的Session ID默认在浏览器关闭时销毁)。
如果需要解决这个问题,我们只需要延长保存Session ID的Cookie的有效期限即可。
String sessionId = session.getId();
Cookie cookie = new Cookie("JSESSIONID", sessionId);
cookie.setPath("/day07/"); // path的值需要与原来的一致才行
cookie.setMaxAge(30 * 60); // 设置为30分钟内有效
response.addCookie(cookie);
浏览器禁用Cookie后如何使用Session技术
从Session的实现原理中,我们可以发现Session的实现需要依赖于Cookie,那么当用户浏览器禁用了Cookie后又该如何使用Session技术呢?
Session的实现原理最基本的是要求用户在每次请求时发送保存有Session ID的信息(如发送保存有Session ID的Cookie)。禁用Cookie后,我们可以为页面中每条请求增加一个参数,用于发送Session ID的值。这样,服务器获取到Session ID后就可以获取到用户独占的Session,为用户服务。
通过response.encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。通过response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写,以此来实现对session数据的共享。
Cookie
Cookie是一种浏览器和服务器交互数据的方式。它是由服务器端创建,但是不会保存在服务器。创建好之后,发送给浏览器。浏览器保存在用户本地,下一次访问网站的时候,就会把该Cookie发送给服务器。
Cookie规范
Http协议提供了有关Cookie的规范,主要包含以下几点:
- Cookie存储的大小上限为4KB。
- 一个服务器最多在客户端浏览器中可以保存20个Cookie。
- 一个浏览器最多可以保存300个Cookie。
值得注意的是,不同浏览器之间不能共享Cookie缓存文件。
Cookie方法
Cookie常用方法如下。
方法 | 说明 |
---|---|
Cookie(String name, String value) | 构造方法,实例化Cookie对象,传入cooke名称和cookie的值 |
public String getName() | 取得Cookie的名字 |
public String getValue() | 取得Cookie的值 |
public void setValue(String newValue) | 设置Cookie的值 |
public void setMaxAge(int expiry) | 设置Cookie的最大保存时间,即cookie的有效期。 |
public int getMaxAge() | 获取Cookies的有效期 |
public void setPath(String url) | 设置cookie的有效路径. |
cookie public String getPath() | 获取cookie的有效路径 |
public void setDomain(String pattern) | 设置cookie的有效域 |
public String getDomain() | 获取cookie的有效域 |
其中,有效路径指的是cookie的有效路径保存在哪里,浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。