会话技术
浏览器和服务器之间为了实现某一个功能,产生了多次的请求和响应,从第一次请求开始到最后一个请求结束,这期间产生的这些请求和响应加在一起就称之为浏览器和服务器之间产生了一次会话。
会话最重要的问题就是如何存储会话产生的数据。
Session概述
Session是javaweb提供的解决会话数据存储相关的技术。
Session是服务器端技术,将会话产生的数据存储在服务器端。
Session技术在服务端为每个客户端创建各自的session对象,用来存储与该客户端会话产生的数据。
每个客户端都使用各自对应的session对象存储会话数据,不会产生混乱。
Session是一个域对象
Session是一个域对象
Session域用来在一个会话范围内共享数据
- 操作API
创建获取session
HttpSession session = request.getSession() |
如果当前会话没有对应的session,这个方法创建Session并返回Session
如果当前会话有对应的session,这个方法直接返回对应session
销毁session
session.invalidate() |
此方法可以立即销毁session
操作session
void | setAttribute(String name, Object value) Binds an object to this session, using the name specified. 向域中写入数据 |
getAttribute(String name) Returns the object bound with the specified name in this session, or null if no object is bound under the name. 从域中获取数据 | |
getAttributeNames() Returns an Enumeration of String objects containing the names of all the objects bound to this session. 获取所有域属性名字组成的枚举 | |
void | removeAttribute(String name) Removes the object bound with the specified name from this session. 从域中删除数据 |
- 特点
生命周期
一种活法:
第一次调用request.getSession()创建session
三种死法
超时:
session连续超过30分钟没人使用,则超时销毁。
可以在web.xml修改session超时时间
自杀:
手动调用session.invalidate()可以立即杀死session
意外身亡:
当服务器非正常关闭时,随着应用的销毁session被销毁
**如果服务器是正常关闭,则服务器会将还存活的session序列化存储到tomcat/work目录下,这个过程叫做sessoin的钝化。
**等服务器下次启动时,会将tomcat/work目录下存储的session恢复回内存,这个过程叫session的活化。
作用范围
在一个会话范围内生效
主要功能
在一个会话范围共享数据
- 发送验证码时将验证码的值存储到session中
校验验证码时从session中取出验证码和用户提交的验证码做比较
根据用户提交的用户名密码,查询数据,错误就提示,正确将用户信息封装到bean中存入session作为登录标记
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.解决乱码 request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //1.获取用户提交的用户名密码 String username = request.getParameter("username"); String password = request.getParameter("password"); //2.查询数据库校验用户名密码 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try{ //--注册数据库驱动 //--获取数据库连接 conn = JDBCUtils.getConn(); //--获取传输器 ps = conn.prepareStatement("select * from user where username = ? and password = ?"); ps.setString(1,username); ps.setString(2,password); //--传输sql执行获取结果集 rs = ps.executeQuery(); //--获取结果数据 if(rs.next()){ //3.正确就登录,重定向回主页 //--将查询到的用户信息转为user对象 User user = new User(); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); user.setNickname(rs.getString("nickname")); user.setEmail(rs.getString("email")); //--获取session HttpSession session = request.getSession(); //--将user对象存储到session中作为登录标记 session.setAttribute("user",user); //--重定向回主页 response.sendRedirect(request.getContextPath()+"/index.jsp"); return; }else{ //3.不正确,转发回到登录页面提示错误消息 request.setAttribute("msg","用户名密码不正确!"); request.getRequestDispatcher("/login.jsp").forward(request,response); return; } }catch (Exception e){ e.printStackTrace(); throw new RuntimeException(e); }finally { //--关闭资源 JDBCUtils.close(conn,ps,rs); } } |
在主页中,根据是否存在登录标记,提示不同信息
<% if(session.getAttribute("user")==null){ %> <a href="<%=request.getContextPath()%>/login.jsp">登录</a> | <a href="<%=request.getContextPath()%>/regist.jsp">注册</a> <% }else{ %> 欢迎回来!<%=((User)session.getAttribute("user")).getUsername()%>! <a href="<%=request.getContextPath()%>/LogoutServlet">[登出]</a> <% } %> |
当用户进行登出操作时,从session中移除登录标记,或直接杀死session,即可登出
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //从session中移除登录标记 //HttpSession session = request.getSession(); //session.removeAttribute("user"); //杀死session HttpSession session = request.getSession(); session.invalidate(); //重定向回主页 response.sendRedirect(request.getContextPath()+"/index.jsp"); } |
Session原理
Session是基于一个名为JSESSIONID特殊的Cookie工作的
服务器中每一个session都会有一个独一无二的session id
当为当前客户端创建session时,会在响应中通过名为JSESSIONID的Cookie将当前session的id发送给浏览器
浏览器之后每次访问都会带着这个JSESSIONID cookie,服务器解析JSESSIONID cookie,得到session的id 找到对应session为当前客户机服务。