## Session
1、概念:服务器端会话技术,再一次会话的多次请求间共享数据,将数据保存在服务器端的对象中,HttpSession
2、快速入门:
1、获取Session对象
HttpSession session = request.getSession();
2、使用HttpSession对象:
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
3、原理:session的实现是依赖于cookie的
4、细节
1、当客户端关闭后,服务器不关闭,两次session是否为同一个?
* 默认情况下,不是。
* 如果需要相同,可以创建cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
package com.Session; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; @WebServlet("/sessionDemo02") public class SessionDemo03 extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //使用session获取数据 HttpSession session = request.getSession(); System.out.println(session); //期望关闭客户端,session也能相同 Cookie c = new Cookie("JSESSIONID", session.getId()); c.setMaxAge(60 * 60); response.addCookie(c); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
2、客户端不关闭,服务器关闭后,两次获取的session是同一个吗?
* 不是同一个,但是要确保数据不丢失。
* session的钝化:
* 在服务器正常关闭之间,将session对象序列化到硬盘上
* session的活化
* 在服务器启动后,将session文件转化为内存中的session对象即可
3、session的失效时间?
1、服务器关闭
2、session对象调用invalidate()
3、session默认实效时间是30分钟
选择性配置修改:Tomcat的web.xml配置文件
<!-- ==================== Default Session Configuration ================= --> <!-- You can set the default session timeout (in minutes) for all newly --> <!-- created sessions by modifying the value below. --> <session-config> <session-timeout>30</session-timeout> </session-config>
5、session的特点
1、session用于存储一次会话的多次请求的数据,存在服务器端
2、session可以存储任意类型,任意大小的数据
* session与cookie的区别:
1、session存储数据在服务器端,而cookie在客户端
2、session没有数据大小限制,cookie有
3、session数据安全,cookie相对于不安全
6、session验证码登录案例
验证码:
package com.ftj.Login; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; /** * @author 21seu.ftj */ @WebServlet("/isCode") public class CheckCode extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //定义验证码图片的宽高 int width = 200; int height = 100; //画验证码 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); //画笔 Graphics g = image.getGraphics(); //设置画笔颜色 g.setColor(Color.PINK); //画一个矩形 g.fillRect(0,0,width,height); //设置画笔颜色 g.setColor(Color.BLUE); //画边框 g.drawRect(0,0,width,height); //设置验证码字符随机的字符串 String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; Random r = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < 4; i++) { int index = r.nextInt(str.length()); char ch = str.charAt(index); sb.append(ch); //把随机字符放进去 g.drawString(ch+"",70+width/5 * i,height/2); } String str_code = sb.toString(); HttpSession session = request.getSession(); session.setAttribute("session_code",str_code); //画干扰线 g.setColor(Color.green); for (int i = 0; i < 10; i++) { int x1 = r.nextInt(width); int x2 = r.nextInt(width); int y1 = r.nextInt(height); int y2 = r.nextInt(height); g.drawLine(x1,x2,y1,y2); } //将验证码输出到页面 ImageIO.write(image,"jpg",response.getOutputStream()); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
登录jsp
<%-- Created by IntelliJ IDEA. User: 21seu.ftj Date: 2020/3/27 Time: 20:08 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录</title> </head> <style> div{ color: red; } </style> <script> window.onload = function () { let img = document.getElementById("img"); img.onclick = function () { img.src = "/isCode?time=" + new Date().getTime(); } } </script> <body> <form action="/loginCheck1" method="post"> <table> <tr> <td>用户名</td> <td> <input type="text" name="username" placeholder="请输入用户名"> </td> </tr> <tr> <td>密码</td> <td> <input type="password" name="password" placeholder="请输入密码"> </td> </tr> <tr> <td>验证码</td> <td> <input type="text" name="checkcode" placeholder="请输入验证码"> </td> </tr> <tr> <td colspan="2"><img id="img" src="/isCode"></td> </tr> <tr> <td colspan="2"> <input type="submit" value="登录"> </td> </tr> </table> <div><%=request.getAttribute("error_msg") == null ? "" : request.getAttribute("error_msg")%> </div> <div><%=request.getAttribute("login_error") == null ? "" : request.getAttribute("login_error")%> </div> </form> </body> </html>
登录验证
package com.ftj.Login; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @author 21seu.ftj */ @WebServlet("/loginCheck1") public class LoginCheck extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置获取参数的编码 request.setCharacterEncoding("utf-8"); //获取参数 String username = request.getParameter("username"); String password = request.getParameter("password"); String checkcode = request.getParameter("checkcode"); //判断验证码是否正确 //1、获取验证码servlet中的session HttpSession session = request.getSession(); String session_code = (String) session.getAttribute("session_code"); //优化1:如果登录成功,退出,验证码不会重新请求,历史记录还在 session.removeAttribute("session_code"); if (session_code != null && session_code.equalsIgnoreCase(checkcode)) { //一致,则去比较用户名密码 if ("ftj".equals(username) && "123456".equals(password)) { //用户名和密码正确 session.setAttribute("user", username); response.sendRedirect("/success.jsp"); } else { //用户名和密码不正确 //登录失败,信息存储到request request.setAttribute("login_error", "用户名或密码错误"); //转发到登录页面 request.getRequestDispatcher("/login.jsp").forward(request, response); } } else { //不一致,登录失败,提示信息存储到request中 request.setAttribute("error_msg", "验证码不一致,登录失败!"); //请求转发到login.jsp request.getRequestDispatcher("/login.jsp").forward(request, response); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }