• Java Servlet实现简单的验证码生成


      验证码存在的意义:不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。

      

      就是类似这个样子滴,PS:(前端页面真不想写,太麻烦了0.0)。


      思考:1.验证码的图片资源哪里来?                         

         2.如何实现点击图片更换验证码? 

         3.如何检验用户输入验证码与生成验证码?

         4.如何返回并获得检验结果?

         5.晚饭吃什么...........午饭吃什么...........


     解决:1.在生成图片的Servlet中设置数据类型为图片--->resp.setContentType("image/jpeg");并将生成的图片输入到 response中,在这过程中生成的验证码字符串需要存放到session中,为后面的验证取数据时作依据。

        2.在js代码中添加函数,改变img的src资源---->codeImg.src="CodeImg?d="+Math.random()这里需要注意一点:如果不追加一个随机数,浏览器的缓存影响,那么每次点击都是同一Servlet产生的图片,起不到改变验证码的效果,这里有几种方法供参考:

         一. GET请求URL后加随机数,让服务器认为不是相同的请求。也可以传一个随机的参数。 例 http://www.example.com/index.php?class=aitcle&page=5&_t=” + new Date().getTime() 
         二. 在ajax发送请求前加上 xmlHttpRequest.setRequestHeader(“If-Modified-Since”,”0”) 
         三. 在ajax发送请求前加上 xmlHttpRequest.setRequestHeader(“Cache-Control”,”no-cache”); 
         四. 使用POST代替GET,浏览器不会对POST做缓存

       3.在检验验证码的Servlet中,获取解决1中session存放的验证码、获取用户表单提交的验证码,进行比较,往session中存放比较结果,返回JSP验证页面。

      4.JSP验证页面通过el表达式获取存放在session中的比较结果,并显示在span标签中。

      5.人生一大困惑.....


     下面上简易版代码(如有纰漏,望指教,多谢):

      结构:JSP验证码界面、Servlet图片生成、Servlet逻辑判断验证码

    VerifyCode.jsp--验证界面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>验证码测试</title>
        <%--外联CSS样式--%>
        <style>
            form{
                border: 1px solid darkcyan;
                width: 300px;
                height: 300px;
                margin: 0px auto;
                text-align: center;
            }
    
            img{
                margin: 30px;
            }
        </style>
    
        <%--js改变验证码函数定义--%>
        <script>
            function changeCode() {
                var codeImg=document.getElementById("verifyCode");
                //这里URL后追加随机数,使程序每次访问的都是不同的资源,防止浏览器缓存,即产生不同的验证码
                codeImg.src="VerifyCodeImg?d="+Math.random();
            }
        </script>
    </head>
    <body>
        <h3>一个验证码的测试</h3>
        <%--通过表单提交到servlet中验证,并返回验证结果在span标签中用el表达式获取messageShow中携带的信息--%>
        <form action="CheckVerifyCode" method="get">
            <h3>验证码</h3>
    
            <%--src为图片生成的Servlet,onclick实现函数变换img的src--%>
            <img src="VerifyCodeImg" alt="Loading" onclick="changeCode()" id="verifyCode">
    
            <%--用户输入--%>
            <input type="text" name="userCode" id="userCode"><br><br>
            <input type="submit" value="提交验证"><br><br>
            
            <%--el获取存在session中的比较结果--%>
            <span id="messageShow">${sessionScope.messageShow}</span>
        </form>
    </body>
    </html>
    VerifyCodeImg--图片生成
    public class VerifyCodeImg extends HttpServlet{
        private static final int WIDTH = 100;//设置验证码图片宽度
        private static final int HEIGHT = 30;//设置验证码图片高度
        private static final int LENGTH = 4;//设置验证码长度
        public static final int LINECOUNT=20;//干扰线的数目
    
        //验证码的字符库
        private static final String str="0123456789"+
                                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
                                        "abcdefghijklmnopqrstuvwxyz";
    
        //通过随机数取字符库中的字符组合成4位验证码
        private static Random random=new Random();
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //设置数据类型为图片
            resp.setContentType("image/jpeg");
    
            //设置不进行缓存
            resp.setHeader("pragma", "no-cache");
            resp.setHeader("cache-control", "no-cache");
            resp.setHeader("expires", "0");
    
    
    
            //获取画笔
            BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_3BYTE_BGR);
            Graphics g=image.getGraphics();
    
            //设置背景颜色并绘制矩形背景
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, WIDTH, HEIGHT);
    
            //验证码的绘制
            String code=drawChar(g);
            System.out.println("验证码:"+code);
    
    
            //随机线的绘制
            for (int i=0;i<LINECOUNT;i++){
                drawLine(g);
            }
    
            //在session中存入当前的code码,便于验证
            req.getSession().setAttribute("code",code);
    
            //绘制图片
            g.dispose();
    
            //将图片输出到response中
            ImageIO.write(image, "JPEG", resp.getOutputStream());
        }
    
    
        //获取不同颜色
        public  Color getColor(){
            return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
        }
    
        //获取字体样式
        public Font getFont() {
            return new Font("Fixedsys", Font.CENTER_BASELINE, 20);
        }
    
        //绘制字符
        public String drawChar(Graphics g){
            String code="";
            g.setFont(getFont());
            for (int i=0;i<LENGTH;i++){
                char c=str.charAt(random.nextInt(str.length()));
                g.setColor(getColor());
                g.drawString(c+"", 20* i + 10, 20);
                code=code+c;
            }
            return code;
        }
    
        //绘制随机线
        public  void drawLine(Graphics g) {
            int x = random.nextInt(WIDTH);
            int y = random.nextInt(HEIGHT);
            int xl = random.nextInt(13);
            int yl = random.nextInt(15);
            g.setColor(getColor());
            g.drawLine(x, y, x + xl, y + yl);
        }
    }
     
    CheckVerifyCode--逻辑判断
    public class CheckVerifyCode extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //返回的信息提示
            String messageShow="";
    
            //用户输入的验证码
            String userCode = request.getParameter("userCode");
    
            //VerifyCodeImg存在session中的验证码
            String rightCode=null;
            Object code = request.getSession().getAttribute("code");
            if(code!=null){
                rightCode=(String) code;
            }
    
            //用户输入和生成验证码的比较,并生成不同的信息提示
            if(userCode.equalsIgnoreCase(rightCode)){
                messageShow="验证成功!!!";
            }else{
                messageShow="验证失败???";
            }
    
            //在session中存放信息提示
            request.getSession().setAttribute("messageShow",messageShow);
    
            //重定向回JSP验证界面,并提示
            response.sendRedirect("VerifyCode.jsp");
        }
    }
     注意:Servlet记得要配置web.xml文件,否则找不见 
  • 相关阅读:
    Mybatis批量插入,是否能够返回id列表
    SVN和Git代码管理小结
    SVN和Git代码管理小结
    Spring异步执行(@Async)2点注意事项
    Spring异步执行(@Async)2点注意事项
    2015年工作中遇到的问题101-110
    Codeforces 263B. Appleman and Card Game
    Codeforces 263A. Appleman and Easy Task
    HDU 482 String
    字符串hash-BKDRHash
  • 原文地址:https://www.cnblogs.com/Alice-Thinker/p/8400318.html
Copyright © 2020-2023  润新知