SESSION是基于cookie技术的,没有cookie,就没有SESSION。
SESSION是将SESSION的ID存储cookie中,而SESSION的数据保存在服务器;每次向网站请求时,只需要发送SESSION的ID,通过SESSION的ID将服务器端保存的用户数据调出来。
Session 工作原理
执行流程:
第一次请求,请求头中没有jsessionid的cookie,当访问到对应的servlet资源时,执行到getSession()会创建HttpSession对象;进而响应时就将session的id作为cookie的value,响应到浏览器 Set-cookie:jsessionid=xxxx;再一次请求时,http请求中就有一个cookie:jsessionid=xxxx信息,那么该servlet就可以通过getSession()获取到jsessionid在服务器内查找对应的session对象,有就使用,无就创建。
Session 创建、获取、销毁
// 获取session对象,服务器底层创建Session HttpSession session = request.getSession();// 获取session对象的唯一标识:sessionID (JSESSIonID=E925DE1EF00F7944537C01A3BC0E2688)String jsessionid = session.getId();// 销毁session对象中的jsessionidsession.invalidate();
Session 共享范围
http域对象之一,服务器中可跨资源共享数据。
// 往 session 中存储 msg
HttpSession session = request.getSession();session.setAttribute("msg", "helloSession");// 获取 msgHttpSession session = request.getSession();Object msg = session.getAttribute("msg");// 删除域对象中的数据session.removeAttribute("msg");
Session 生命周期
一般都是默认值 30 分钟,无需更改。取决于 Tomcat 中 web.xml 默认配置:
session-config>
30
Session生命周期结束时机:
浏览器关闭:销毁cookie中的jsessionid=xxx,原session对象会保留默认30min后才销毁,30分钟后为新的session;session销毁:主动调用 session.invalidate() 方法后,立即将session对象销毁,再次访问时会创建新的session。
- Session 应用
2.1 案例:使用验证码登陆和共享用户信息表单数据:
表单数据:
验证码图片生成:
@WebServlet(name = "CreateCodeServlet", urlPatterns = "/createCode")
public class CreateCodeServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int width = 60;//定义图片宽度 int height = 32;//定义图片高度 //创建图片对象 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //创建画笔对象 Graphics g = image.getGraphics(); //设置背景颜色 g.setColor(new Color(0xDCDCDC)); g.fillRect(0, 0, width, height);//实心矩形 //设置边框 g.setColor(Color.black); g.drawRect(0, 0, width - 1, height - 1);//空心矩形 Random rdm = new Random(); //画干扰椭圆 for (int i = 0; i < 50; i++) { int x = rdm.nextInt(width); int y = rdm.nextInt(height); g.drawOval(x, y, 0, 0); } //产生随机字符串 String hash1 = Integer.toHexString(rdm.nextInt()); //生成四位随机验证码 String capstr = hash1.substring(0, 4); //将产生的验证码存储到session域中,方便以后进行验证码校验! request.getSession().setAttribute("existCode", capstr); System.out.println(capstr); g.setColor(new Color(0, 100, 0)); g.setFont(new Font("Candara", Font.BOLD, 24)); g.drawString(capstr, 8, 24); g.dispose(); //将图片响应到浏览器 response.setContentType("image/jpeg"); OutputStream strm = response.getOutputStream(); ImageIO.write(image, "jpeg", strm); strm.close(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }}
登陆 Servlet:
@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); // 获取输入的验证码 String validateCode = request.getParameter("validateCode"); // 将输入的验证码和产生的随机验证码进行校验 String existCode = (String) request.getSession().getAttribute("existCode"); if (validateCode.equals(existCode)) { String username = request.getParameter("username"); String password = request.getParameter("password"); UserDao userDao = new UserDaoImpl(); Userinfo inputUserinfo = new Userinfo(); inputUserinfo.setUsername(username); inputUserinfo.setPassword(password); try { Userinfo existUserinfo = userDao.login(inputUserinfo); System.out.println(existUserinfo); if (null == existUserinfo) { // 登陆失败,跳转登陆页面,转发 request.getRequestDispatcher("/login.html").forward(request, response); } else { // 登陆成功,跳转到首页,重定向 request.getSession().setAttribute("existUser", existUserinfo); response.sendRedirect("/demo/show"); } } catch (SQLException e) { e.printStackTrace(); } } else { // 校验不通过,跳转到登陆页面 request.getRequestDispatcher("/login.html").forward(request, response); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }}
展示 Servlet:
@WebServlet(name = "ShowIndexServlet", urlPatterns = "/show")
public class ShowIndexServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
Userinfo existUserinfo = (Userinfo) request.getSession().getAttribute("existUser");
if (null != existUserinfo) { // 在登陆状态 response.getWriter().write("欢迎回来," + existUserinfo.getUsername()); } else {
// 不在登陆状态,根据需求:①提示 ②跳转到登陆页 //response.getWriter().write("您还未登陆,请登陆");
response.sendRedirect("/demo/login.html"); } }
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }}
如果网页使用session,而需要使用Python爬虫爬取页面数据,可以使用requests.session,他会在get,post等时自动提交cookie,无需自己处理。一般登录时,服务器会返回set-cookie来设置客户端的jsessionid。如果使用request.post/get的话,则提交时需要自己处理一下,将cookie中的jsessionid取出传入报文头再提交
转载:
https://simple.blog.csdn.net/article/details/105674613?spm=1001.2101.3001.6650.3&utm_medium=distribute.wap_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.wap_blog_relevant_pic&depth_1-utm_source=distribute.wap_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.wap_blog_relevant_pic



