• Java Web(四) 一次性验证码的代码实现


         其实实现代码的逻辑非常简单,真的超级超级简单。

         1、在登录页面上login.jsp将验证码图片使用标签<img src="xxx">将绘制验证码图片的url给它

         2、在服务器端就两个servlet,一个就是用来绘制验证码图片的VerifyCodeServlet,另一个就是登录时验证验证码是否点写正确或是否重复提交的LoginServlet

         3、在VerifyCodeServlet中,将验证码的四个字母存入session中,然后在LoginServlet中,将请求中提交过来的验证码与session中的进行对比,如果正确,则验证成功,并且将session中的验证码删除,为什么要删除?保证session中的数据只能被用一次,防止重复提交数据,如果不正确,就使用request,将错误信息保存,然后请求转发到登录页面显示错误信息,如果发现session中的数据为null,说明重复提交了数据,也将错误信息用同样的方法返回到登录页面。

         难点就在于:VerifyCodeServlet的代码实现.对绘图的代码不是很熟悉。


    login.jsp

      <body>
                <%
            String msg = (String)request.getAttribute("msg");
            if(msg != null){
                out.print(msg);
            }
        %>
        
        <form action="/test01/LoginServlet" method="post">
            用户名:<input type="text" name="username" /> <br/>
            验证码:<input type="text" name="verifyCode" size="5" /> <img src="/test01/VerifyCodeServlet" /> <br/>
            <input type="submit" value="提交"/>
        </form> 
      </body>
    View Code

    VerifyCodeServlet.java

        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
    
             //声明验证码
            int width = 60;
            int height = 30;
            String data = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghijklmnpqrstuvwxyz";    //随机字符字典,其中0,o,1,I 等难辨别的字符最好不要
            Random random = new Random();//随机类
            //1 创建图片数据缓存区域(核心类)
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//创建一个彩色的图片
            //2 获得画板(图片,ps图层),绘画对象。
            Graphics g = image.getGraphics();
            //3 选择颜色,画矩形3,4步是画一个有内外边框的效果
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, width, height);
            //4白色矩形
            g.setColor(Color.WHITE);
            g.fillRect(1, 1, width-2, height-2);
            
            /**1 提供缓存区域,为了存放4个随机字符,以便存入session */
            StringBuilder builder = new StringBuilder();
            
            //5 随机生成4个字符
                        //设置字体颜色
            g.setFont(new Font("宋体", Font.BOLD&Font.ITALIC, 20));
            for(int i = 0 ; i < 4 ;i ++){
                //随机颜色
                g.setColor(new Color(random.nextInt(255),random.nextInt(255), random.nextInt(255)));
                
                //随机字符
                int index = random.nextInt(data.length());
                String str = data.substring(index, index + 1);
                
                /**2 缓存*/
                builder.append(str);
                
                //写入
                g.drawString(str, (width / 6) * (i + 1) , 20);                     
            }
            //给图中绘制噪音点,让图片不那么好辨别
            for(int j=0,n=random.nextInt(100);j<n;j++){
                g.setColor(Color.RED);
                g.fillRect(random.nextInt(width),random.nextInt(height),1,1);//随机噪音点
            }
    
            
            /**3 获得随机数据,并保存session*/
            String tempStr = builder.toString();
            request.getSession().setAttribute("sessionCacheData",tempStr);
            
            
            //.. 生成图片发送到浏览器 --相当于下载
            ImageIO.write(image, "jpg", response.getOutputStream());
        }
    View Code

    LoginServlet.java

        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //1 获得用户输入的验证码
            String verifyCode = request.getParameter("verifyCode");
            //2 获得服务器session 存放数据 ,如果没有返回null
            String sessionCacheData = (String) request.getSession().getAttribute("sessionCacheData");
            // *将服务器缓存session数据移除
            request.getSession().removeAttribute("sessionCacheData");
            // ** 判断服务器是否存在
            if(sessionCacheData == null){
                request.setAttribute("msg", "请不要重复提交");
                request.getRequestDispatcher("/login.jsp").forward(request, response);
                return;
            }
            //3 比较
            if(! sessionCacheData.equalsIgnoreCase(verifyCode)){
                //用户输入错误
                // * 存放request作用域
                request.setAttribute("msg", "验证码输入错误");
                // * 请求转发
                request.getRequestDispatcher("/login.jsp").forward(request, response);
                
                return;
            }
            
            //...... 登录操作
    
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            this.doGet(request, response);
        }
    
    }
    View Code

    效果图:

        

        验证码错误时:

          

    注意:

        如果要拷贝代码的话,需要改就应该就是那几处url,你的肯定跟我的不一样,并且有些人设置的servlet的访问路径也不一样,所以拷贝的话只需要拷贝关键代码即可。

      

  • 相关阅读:
    uva10986 堆优化单源最短路径(pas)
    动态规划②——线性动态规划(背包)
    UVA567
    动态规划①——记忆化搜索
    网络号与主机号的区分与计算(转)
    故障处理-ORA-00376/ORA-01110
    Oracle的自动统计信息不收集直方图的信息
    Oracle 11g的Redo Log和Archive Log的分析方法
    SQL优化 1
    oracle 11g 通过在线重定义方式修改表结构
  • 原文地址:https://www.cnblogs.com/whgk/p/6426072.html
Copyright © 2020-2023  润新知