- 什么是Session?
- 实现原理
- Session的操作
- Session持久化处理
- Session的细节
跳转到目录 Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源时,其他web资源再从用户各自的session中取出数据为用户服务.总而言之,将数据保存在服务器.
Session的特点- session 用于存储一次会话的多次请求的数据
- session 数据存储在服务器中
- session 可以存储任意类型,任意大小的数据
跳转到目录
流程:
首先客户端登录账号密码访问服务器, 服务器收到请求后获取到参数内容后, 创建一个session对象
, 获取sessionId, 将sessionid保存到cookie中(Cookie c = new Cookie("JSESSIONID", sessionid)
), 然后通过response.addCookie(c)
响应给客户端, 获取到的参数也要保存到session中, 当客户端再次请求服务端时, 就会携带带有sessionid的cookie请求服务器, 此时通过sessionid获取session对象, 再从session中获取共享数据~
Session其本质就是一个会话Cookie(浏览器关闭后,Session就失效了)
- 使用Cookie和Session发送请求的内容
跳转到目录 一、 获取Session对象
request.getSession(true)
: 获取Session对象,如果没有Session对象,直接创建一个新的返回,缺省值request.getSession(false)
: 获取Session对象,如果没有返回nullrequest.getSession()
: 和参数为true的一样
二、 设置共享数据
- 往Session中存储数据
session.setAttribute(String name, Object value);
- 从Session中取出数据
Object value = session.getAttribute(String key);
三、 删除Session(用户注销登录)
- 删除Session中指定属性名的值.
session.removeAttribute("currentName");
- 销毁Session对象(Session中所有属性都不存在了)
session.invalidate();
四、 Session的超时管理 超时:在访问当前的资源的过程中,不和网页进行任何的交互,超过设定的时间就是超时.超时后就会销毁Session void setMaxInactiveInterval(int interval)
在服务器中有默认的配置为30分钟,通常不需要去修改 五、 URL重写(在url后面拼接jsessionid,解决浏览器禁用Cookie)
问题: 当浏览器禁用Cookie之后,那么我们的jsessionid就不能在浏览器中保存,那么后面的请求中就不会将jsessionid发送到服务器,服务器这面就找不到数据 解决方案:
- 在url后手动的拼接上jsessionid
String jessionid = session.getId();
- 使用响应对象中的encodeURL(String path)实现jsessionid的自动拼接
String path = response.encodeURL("/session/list");
跳转到目录 由于Session使用 JSESSIONID与 客户端联系起来, 所以客户端没有id , 也就无法找到session; id保存 到Cookie中 , 导致 关闭浏览器,cookie默认消失 , 随着id就消失了.一旦关闭浏览器 , session无法再使用.所谓 session持久化,将 JSESSIONID 持久化存储到浏览器中, 再次打开浏览器, id继续使用.
解决方案: 访问一次服务器,然后关闭浏览器,再访问一次:两次session对象一致;将保存JSESSIONID
的cookie设置时间 , 持久存储.
@WebServlet(urlPatterns = "/save2")
public class Session4Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
/*
由于 session对象由 Tomcat创建 , 所以只能通过request对象, 获取 Session对象.
getSession() : 获取Session .
保存数据 , 与 ServletContext , Request , PageContext对象 存储方法一致.
此四个对象 ,叫做四大域对象, 存储范围不一样.
ServletContext > Session > Request > PageContext
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 提交的参数 , 保存 Session 中 (在url中拼接参数 ?username=gzy&password=123)
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println( request.getRemoteAddr()+":[" +username+":"+password+"]" );
// 保存到session 中
HttpSession session = request.getSession();
/*
* 由于Session使用 JSESSIONID与 客户端联系起来, 所以客户端没有id , 也就无法找到session;
* id保存 到Cookie中 , 导致 关闭浏览器,cookie默认消失 , 随着id就消失了.一旦关闭浏览器 ,
* session无法再使用.所谓 session持久化,将 JSESSIONID 持久化存储到浏览器中, 再次打开浏览器, id继续使用.
* */
String sid = session.getId();
Cookie jsessionid = new Cookie("JSESSIONID", sid);
jsessionid.setMaxAge(60*2);
response.addCookie(jsessionid);
// =================================================
session.setAttribute("username", username);
session.setAttribute("password", password);
}
}
@WebServlet(urlPatterns = "/getattr")
public class Session3Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
// 获取 Session 对象
HttpSession session = request.getSession();
// 获取 保存的数据
Object username = session.getAttribute("username");
Object password = session.getAttribute("password");
response.getWriter().println(username+":"+password);
}
}
Session的细节
跳转到目录
- 一般的,我们存储到Session中的属性名称,要唯一,起名规范XXX_IN_SESSION
session.setAttribute("USER_IN_SESSION","ZYGui");
- 若需要把多个数据存放到Session中,就要调用setAttribute方法N次,一般将存储的数据封装成一个对象,然后存储到Session中.把用户的信息,封装到user对象. session.setAttribute(“USER_IN_SESSION”, user对象);
- 如果多台服务器需要共享Session,此时Session中的对象,必须实现java.io.Serializable(才能在网络上传输) 序列化: 把对象信息存储为二进制. 反序列化: 把二进制信息恢复成对象.