zoukankan      html  css  js  c++  java
  • 利用Session实现一次验证码

    Session可避免表单的重复提交:实现一次表单提交,可避免恶意提交;

    1.首先建立一个Servlet类:ValidateColorServlet,里边有获取验证码的方法,并且验证码是大小写区分:

    public class ValidateColorServlet extends HttpServlet {
    
        public static final String CHECK_CODE_KEY = "CHECK_CODE_KEY";
        
        private static final long serialVersionUID = 1L;
        
        //设置验证图片的宽度, 高度, 验证码的个数
        private int width = 152;
        private int height = 40;
        private int codeCount = 6;
        
        //验证码字体的高度
        private int fontHeight = 4;
        
        //验证码中的单个字符基线. 即:验证码中的单个字符位于验证码图形左上角的 (codeX, codeY) 位置处
        private int codeX = 0;
        private int codeY = 0;
        
        //验证码由哪些字符组成
        char [] codeSequence = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz23456789".toCharArray();
        
        //初始化验证码图形属性
        public void init(){
            fontHeight = height - 2;
            codeX = width / (codeCount + 2);
            codeY = height - 4;
        }
    
        public void service(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //定义一个类型为 BufferedImage.TYPE_INT_BGR 类型的图像缓存
            BufferedImage buffImg = null;
            buffImg = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        
            //在 buffImg 中创建一个 Graphics2D 图像
            Graphics2D graphics = null;
            graphics = buffImg.createGraphics();
            
            //设置一个颜色, 使 Graphics2D 对象的后续图形使用这个颜色
            graphics.setColor(Color.WHITE);
            
            //填充一个指定的矩形: x - 要填充矩形的 x 坐标; y - 要填充矩形的 y 坐标; width - 要填充矩形的宽度; height - 要填充矩形的高度
            graphics.fillRect(0, 0, width, height);
            
            //创建一个 Font 对象: name - 字体名称; style - Font 的样式常量; size - Font 的点大小
            Font font = null;
            font = new Font("", Font.BOLD, fontHeight);
            //使 Graphics2D 对象的后续图形使用此字体
            graphics.setFont(font);
            
            graphics.setColor(Color.BLACK);
            
            //绘制指定矩形的边框, 绘制出的矩形将比构件宽一个也高一个像素
            graphics.drawRect(0, 0, width - 1, height - 1);
            
            //随机产生 15 条干扰线, 使图像中的认证码不易被其它程序探测到
            Random random = null;
            random = new Random();
            graphics.setColor(Color.GREEN);
            for(int i = 0; i < 55; i++){
                int x = random.nextInt(width);
                int y = random.nextInt(height);
                int x1 = random.nextInt(20);
                int y1 = random.nextInt(20);
                graphics.drawLine(x, y, x + x1, y + y1);
            }
            
            //创建 randomCode 对象, 用于保存随机产生的验证码, 以便用户登录后进行验证
            StringBuffer randomCode;
            randomCode = new StringBuffer();
            
            for(int i = 0; i < codeCount; i++){
                //得到随机产生的验证码数字
                String strRand = null;
                strRand = String.valueOf(codeSequence[random.nextInt(36)]);
                
                //把正在产生的随机字符放入到 StringBuffer 中
                randomCode.append(strRand);
                
                //用随机产生的颜色将验证码绘制到图像中
                graphics.setColor(Color.BLUE);
                graphics.drawString(strRand, (i + 1)* codeX, codeY);
            }
            
            //再把存放有所有随机字符的 StringBuffer 对应的字符串放入到 HttpSession 中
            request.getSession().setAttribute(CHECK_CODE_KEY, randomCode.toString());
            
            //禁止图像缓存
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            
            //将图像输出到输出流中
            ServletOutputStream sos = null;
            sos = response.getOutputStream();
            ImageIO.write(buffImg, "jpeg", sos); 
            sos.close();
        }
    }

    2.index.jsp页面,输入用户名字,输入验证码:checkCode:<input type="text" name="CHECK_CODE_PARAM_NAME"/>;获取验证码:是以插入图片的形式获取的<img alt="" src="<%=request.getContextPath() %>/validateColorServlet">,然后form表单提交到Servlet类:CheckCodeServlet

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <font color="red">
            <%=session.getAttribute("message")==null ? "" : session.getAttribute("message") %>
        </font>
        
        <form action="<%=request.getContextPath() %>/checkCodeServlet" method="post">
        
            name:<input type="text" name="name"/>
            <br><br>
            checkCode:<input type="text" name="CHECK_CODE_PARAM_NAME"/>
        
            <img alt="" src="<%=request.getContextPath() %>/validateColorServlet">
            <br><br>
            <input type="submit" value="Submit"/>
        </form>
    </body>
    </html>

    3.建立一个Servlet类:CheckCodeServlet,获取表单输入的验证码和通过session的getsession()方法获取系统给予的验证码,并进行判断,看是否相等,然后重定向到index.jsp页面,输出结果;

    public class CheckCodeServlet extends HttpServlet {
        
        private static final long serialVersionUID = 1L;
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            
            //1. 获取请求参数: CHECK_CODE_PARAM_NAME
            String paramCode = request.getParameter("CHECK_CODE_PARAM_NAME");
            
            //2. 获取 session 中的 CHECK_CODE_KEY 属性值
            String sessionCode = (String)request.getSession().getAttribute("CHECK_CODE_KEY");
            
            System.out.println(paramCode);
            System.out.println(sessionCode); 
            
            //3. 比对. 看是否一致, 若一致说明验证码正确, 若不一致, 说明验证码错误
            if(!(paramCode == null && !paramCode.equals(sessionCode))){
                request.getSession().setAttribute("message", "验证码不一致!");
                response.sendRedirect(request.getContextPath() + "/check/index.jsp");
                return;
            }
            
            System.out.println("受理请求!");
            
        }
    
    }

    4.lib下的web.xml文件为:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
      
      <servlet>
        <description></description>
        <display-name>ValidateColorServlet</display-name>
        <servlet-name>ValidateColorServlet</servlet-name>
        <servlet-class>com.lanqiao.javatest.ValidateColorServlet</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>ValidateColorServlet</servlet-name>
        <url-pattern>/validateColorServlet</url-pattern>
      </servlet-mapping>

    <servlet> <description></description> <display-name>CheckCodeServlet</display-name> <servlet-name>CheckCodeServlet</servlet-name> <servlet-class>com.lanqiao.javatest.CheckCodeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CheckCodeServlet</servlet-name> <url-pattern>/checkCodeServlet</url-pattern> </servlet-mapping> </web-app>
  • 相关阅读:
    Windows Azure Storage (17) Azure Storage读取访问地域冗余(Read Access – Geo Redundant Storage, RA-GRS)
    SQL Azure (15) SQL Azure 新的规格
    Azure China (5) 管理Azure China Powershell
    Azure China (4) 管理Azure China Storage Account
    Azure China (3) 使用Visual Studio 2013证书发布Cloud Service至Azure China
    Azure China (2) Azure China管理界面初探
    Azure China (1) Azure公有云落地中国
    SQL Azure (14) 将云端SQL Azure中的数据库备份到本地SQL Server
    [New Portal]Windows Azure Virtual Machine (23) 使用Storage Space,提高Virtual Machine磁盘的IOPS
    Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
  • 原文地址:https://www.cnblogs.com/lxnlxn/p/5824872.html
Copyright © 2011-2022 走看看