Session学习---Session池、验证码

本篇博客知识点

1.演示request、session、application(ServletContext)的生命周期
2.Session池的工作原理
3.网页验证码

演示request、session、application(ServletContext)的生命周期
主要思路: 在SaveServlet中 设置三个容器的name属性,分别赋值。再写个超链接个GetServlet中去读取出来,输出到页面。

在IE中存、在IE中拿(浏览器未关闭) session 和application拿到了
这里写图片描述

在IE中存。在360浏览器中拿 只拿到了application
这里写图片描述

总结:
request 生命周期是一次请求,一个request。所以Getsevlet和SaveSevlet 中是两个request 因此拿不到
session 生命周期和浏览器是一起的,浏览器不关闭,同一个浏览器上拿到的session是同一个 因此IE在IE上拿的到 360浏览器拿不到IE存的session
application 生命周期是和服务器一起的 服务器一直未关闭,所以不管什么浏览器都能拿到applicatton容器内的值

SavaServlet.java

package cn.hncu.servlets2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SaveServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        // 通过三个容器request、session、application 分别设置三个属性 看看能在哪儿拿到 推出他们的生命周期  
        String name = "胡龙华";
        request.setAttribute("name", name+"_request");

        HttpSession session = request.getSession();
        session.setAttribute("name", name+"_session");

        ServletContext application = getServletContext();
        application.setAttribute("name", name+"_application");

        out.println(" <a href='GetServlet'>查看三个容器属性</a><br/>");
        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

GetServlet.java

package cn.hncu.servlets2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GetServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        String requestName = (String) request.getAttribute("name");
        out.println("requestName:"+requestName+"<br/>");

        String sessionName = (String) request.getSession().getAttribute("name");
        out.println("sessionName:"+sessionName+"<br/>");

        String applicationName = (String) getServletContext().getAttribute("name");
        out.println("applicationName:"+applicationName);
        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

Session池工作原理

当浏览器访问服务器时,服务器会去读取浏览器中的一个cookie ,这个cookie的name 为 JESSIONID 拿到他的value值,SESSIONID 去Session池匹配,找到了建立连接,未找到就重新创建一个SESSIONID并且写到cookie里
这里写图片描述

通过不断维护这个seesion池,完成回话。session池的底层原理是HashMap();

有的浏览器禁用了cookie,那么按照这种方式就没办法建立会话连接,因此为了兼容,可以值禁用cookie时,通过地址栏把JESSIONID发给服务器格式如下:

http://localhost:8080/cookieSessionWeb/GetServlet;jsessionid=2110E3A20145E759FEB31680E3ABB872

正是因为这种兼容方式,容易系统容易被人黑。用户退出后Session默认的时间是30分钟,因此要让用户安全退出—在Session池中去掉哪条记录

        //安全退出
        HttpSession s = request.getSession();
        s.invalidate(); //让session失败
        out.println("您已经安全退出!");

另外一种情况是:用户不小心关闭了浏览器,想要重新打开恢复刚刚的页面信息(恢复刚刚session通话),如何做? — 服务器像用户写一个普通cookie 把刚刚的SESSIONID放过去就好了

//本来,浏览器关闭之后重启,上一次的用户临时信息是访问不了的
        //把cookie和session技术联合起来,实现让用户不小心关闭浏览器,用户的临时信息还能在5分钟之内重启浏览器有效
        //我们在服务器端写代码手动创建一个 JSESSIONID=....的普通cookie,发向客户端
        String id = request.getSession().getId();//拿到该用户的session id
        Cookie c = new Cookie("JSESSIONID",id);
        c.setMaxAge(60*5);//5分钟
        c.setPath(request.getContextPath());
        response.addCookie(c);

网页验证码

逻辑示意图: 每个用户都在请求验证码,因此必须放在Session中!!!!
这里写图片描述

CodeImgServlet.java代码 生成验证码

package cn.hncu.servlet2;


import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CodeImgServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        //☆1☆--相比纯java方式有变化的地方
        resp.setContentType("image/jpeg");//设置http响应头---告诉浏览器我现在发的是这个图片格式的数据,你用相应的方式来解析

        //定义图片的宽和高
        int w=60;
        int h=30;

        //声明一个RGB格式的内存中的图片
        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics g = img.getGraphics();

        //把背景变白色
        g.setColor(Color.white);
        g.fillRect(0, 0, w, h);
        //设置字体
        g.setFont(new Font("aa",Font.BOLD,18));

        //产生并draw出4个随机数字
        Random r = new Random();
        String sCode="";
        for(int i=0;i<4;i++){
            int a = r.nextInt(10);//生成0~9之间的随机整数
            int y = 15+r.nextInt(20);//产生随机的垂直位置
            //产生随机颜色
            Color c = new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256));
            g.setColor(c);

            g.drawString(""+a, i*15, y);
            sCode +=a; //生成真正的验证码
        }
        req.getSession().setAttribute("sCode", sCode);//把验证码标准答案存入session容器

        //画几条干扰线
        for(int i=0;i<10;i++){
            //产生随机颜色
            Color c = new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256));
            g.setColor(c);
            g.drawLine(r.nextInt(60), r.nextInt(30), r.nextInt(60), r.nextInt(30));
        }

        g.dispose();//类似于IO中的flush(),把图形数据刷到img中
        //把内存图片img对象保存到一个jpg文件
        ImageIO.write(img, "JPEG", resp.getOutputStream() );//☆2☆

    }
}

LoginServlet.java

package cn.hncu.servlet2;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
        out.println("<HTML>");
        out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
        out.println("  <BODY>");

        //获取用户上传参数中的验证码--待测数据
        String code = request.getParameter("code");

        //获取session中验证码的标准答案
        HttpSession session =  request.getSession();
        String sCode = (String)session.getAttribute("sCode");
        session.removeAttribute("sCode");//验证码用过一次就要让它失效,无论这次是否成功

        //判断验证码是否正确
        if(sCode==null || !sCode.equals(code)){
            out.println("验证码输入错误!");
        }else{//验证码正确
            //把用户名和密码提交给后台数据库去校验----这里简单模拟一下
            String nm = request.getParameter("name");
            String pwd = request.getParameter("pwd");
            if(nm!=null && nm.trim().equals(pwd)){//假设这样算登录成功
                out.println("登录成功!");
            }else{
                out.println("登录失败!");
            }
        }

        out.println("  </BODY>");
        out.println("</HTML>");
        out.flush();
        out.close();
    }

}

页面和xml

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Cookie-Session技术演示</title>
  </head>

  <body>
    <h2>上一段Cookie技术演示</h2>

    <a href="CookieDemo1">Cookie技术演示1</a> <br/>

    <a href="servlet/CookieDemo2">该servlet用于演示Cookie的访问权限</a>
    <br/><br/>

    <a href="LoginServlet">利用Cookie技术显示上次登录的时间</a>
    <br/><br/>

    <a href="TestCookieNumServlet">测试浏览器支持cookie的数量和长度</a>
    <br/><br/>


    <a href="jsps/show.jsp">案例:利用cookie记录用户最近访问的图片信息</a>
    <br/><br/>

    <a href="jsps/cookie.jsp">前端页面中用js来操作cookie技术演示</a>
    <br/><br/>

    <hr/>
    <h2>下一段演示Session技术</h2>
    <a href="jsps/contain.jsp"> request, session, application(ServletContext) 这三个容器生命周期对比演示</a>
    <br/>
    <a href="LogoutServlet">安全退出</a>

    <br/><br/>
    <script type="text/javascript">
         function changeImg(){
             var img = document.getElementById("codeImg");
             img.src="code?"+new Date().getTime();
         }
    </script>
    <h2>用户注册</h2>
     <form action="LoginServlet2" method="post">
            姓名:<input type="text" name="name"><br/>
            密码:<input type="password" name="pwd"><br/>
            验证码:<input type="text" name="code"/><img id="codeImg" src="code"/><a href="javascript:changeImg();">看不清</a><br/>
          <input type="submit" value="注册">
     </form>
  </body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>CookieDemo1</servlet-name>
    <servlet-class>cn.hncu.servlet.CookieDemo1</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>CookieDemo2</servlet-name>
    <servlet-class>cn.hncu.servlet.CookieDemo2</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.LoginServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>TestCookieNumServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.TestCookieNumServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>ShowServlet</servlet-name>
    <servlet-class>cn.hncu.servlet.ShowServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>SaveServlet</servlet-name>
    <servlet-class>cn.hncu.servlet2.SaveServlet</servlet-class>
  </servlet>
  <servlet>
    <servlet-name>GetServlet</servlet-name>
    <servlet-class>cn.hncu.servlet2.GetServlet</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>LogoutServlet</servlet-name>
    <servlet-class>cn.hncu.servlet2.LogoutServlet</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>LoginServlet2</servlet-name>
    <servlet-class>cn.hncu.servlet2.LoginServlet</servlet-class>
  </servlet>

  <servlet>
    <servlet-name>CodeImgServlet</servlet-name>
    <servlet-class>cn.hncu.servlet2.CodeImgServlet</servlet-class>
  </servlet>





  <servlet-mapping>
    <servlet-name>CookieDemo1</servlet-name>
    <url-pattern>/CookieDemo1</url-pattern>
  </servlet-mapping>    
  <servlet-mapping>
    <servlet-name>CookieDemo2</servlet-name>
    <url-pattern>/servlet/CookieDemo2</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>TestCookieNumServlet</servlet-name>
    <url-pattern>/TestCookieNumServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>ShowServlet</servlet-name>
    <url-pattern>/ShowServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>SaveServlet</servlet-name>
    <url-pattern>/SaveServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>GetServlet</servlet-name>
    <url-pattern>/GetServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LogoutServlet</servlet-name>
    <url-pattern>/LogoutServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginServlet2</servlet-name>
    <url-pattern>/LoginServlet2</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>CodeImgServlet</servlet-name>
    <url-pattern>/code</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

重写URL技术:当流浪器禁用cookie时,正常的方式就无法建立session,重写URL技术可以完美的解决这个问题。代码如下encodeURL

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Cookie-Session技术演示</title>
  </head>

  <body>
    <h2>request, session, application(ServletContext) 这三个容器生命周期对比演示</h2>
    <pre>
      request:代表一次请求,每次请求的容器是独立的。
                          不同的请求之间是无法共享该容器中的数据的。
      session:代表一个用户,通常是指同一个浏览器,
                         该浏览器中的多个请求甚至是多个页面是共享同一个session容器的。
                         如果浏览器关闭再打开,则是另一个session容器,无法共享到上一次的session。
      application:代表一个项目(我们平时理解的一个网站)。
                        不但是多个请求,甚至是多个用户(浏览器)都是共享该容器。只要Tomcat不关闭,这个容器一直存在。
                         但如果Tomcat关闭(或项目停止运行)则该容器消亡。
    </pre>

    <!-- 重写url技术: 
        解决浏览器禁用cookie,导致浏览器在发出请求时不发送JSESSIONID这个特殊的cookie,
         从面出现服务器不认识该session用户,由此造成无法共享session中的信息。
      ---每次请求都会被服务器当成一个新用户(session)。
       重写url技术的本质是: 我们写代码在请求url后面手动加字符串: ";jsessionid=29E4A2378278DAE4"
     -->



    <!-- 往容器中放值 -->
    <!-- 非重写url的方式,,,无法突破浏览器“禁用cookie”的情况
       <form action="<%=request.getContextPath()%>/SaveServlet" method="post">
     -->

     <!-- 重写url的方式 ,,能突破浏览器“禁用cookie”的情况 -->
     <%
       String url = response.encodeURL( request.getContextPath()+"/SaveServlet" ); //重写url,即在参数(url)后面手动添加";jsessionid=5D787A90163F222827456857608E243D"
       System.out.println("url:"+url);
    %>
    <form action="<%=url%>" method="post">
       Name:<input type="text" name="name" /><br/>
       <input type="submit"/>
    </form>

    <br/>
    <% 
         url= response.encodeURL( request.getContextPath()+"/GetServlet" ); //重写url,即在参数(url)后面手动添加";jsessionid=5D787A90163F222827456857608E243D"
    %>
    <a href="<%=url%>">读取容器中的值</a>


  </body>
</html>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值