zoukankan      html  css  js  c++  java
  • java 理解如何实现图片验证码 傻瓜都能看懂。

    先代码后解释:

    只要把代码复制到你的项目中就可以了。

    代码:

    验证码工具类:

    package cn.happy.util.imagesVerTion;
    
    /**
     * Author: SamGroves
     *
     * Description: 验证码生成器
     *
     * Date: 2017/8/29
     */
    import javax.servlet.http.HttpServletRequest;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.OutputStream;import java.util.HashMap;
    import java.util.Map;import java.util.Random;
    
    public class Captcha {
        private static char mapTable[] = {
                '0', '1', '2', '3', '4', '5',
                '6', '7', '8', '9', '0', '1',
                '2', '3', '4', '5', '6', '7',
                '8', '9'};
        public static Map<String, Object> getImageCode(int width, int height, OutputStream os) {
            Map<String,Object> returnMap = new HashMap<String, Object>();//定义了一个集合,
            if (width <= 0) width = 60;
            if (height <= 0) height = 20;
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 获取图形上下文
            Graphics g = image.getGraphics();
            //生成随机类
            Random random = new Random();
            // 设定背景色
            g.setColor(getRandColor(200, 250));
            g.fillRect(0, 0, width, height);
            //设定字体
            g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
            // 随机产生168条干扰线,使图象中的认证码不易被其它程序探测到
            g.setColor(getRandColor(160, 200));
            for (int i = 0; i < 168; i++) {
                int x = random.nextInt(width);
                int y = random.nextInt(height);
                int xl = random.nextInt(12);
                int yl = random.nextInt(12);
                g.drawLine(x, y, x + xl, y + yl);
            }
            //取随机产生的码
            String strEnsure = "";
            //4代表4位验证码,如果要生成更多位的认证码,则加大数值
            for (int i = 0; i < 4; ++i) {
                strEnsure += mapTable[(int) (mapTable.length * Math.random())];
                // 将认证码显示到图象中
                g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
                // 直接生成
                String str = strEnsure.substring(i, i + 1);
                // 设置随便码在背景图图片上的位置
                g.drawString(str, 13 * i + 20, 25);
            }
            // 释放图形上下文
            g.dispose();
            returnMap.put("image",image);//把验证码的图片放到了map集合中。
            returnMap.put("strEnsure",strEnsure);//把验证码的文字放入到了map集合中。
           /* request.getSession().setAttribute("strEnsure",strEnsure);*/
            System.out.println(strEnsure+"之后的strEnsure");
            return returnMap;
        }
        //给定范围获得随机颜色
        static Color getRandColor(int fc, int bc) {
            Random random = new Random();
            if (fc > 255) fc = 255;
            if (bc > 255) bc = 255;
            int r = fc + random.nextInt(bc - fc);
            int g = fc + random.nextInt(bc - fc);
            int b = fc + random.nextInt(bc - fc);
            return new Color(r, g, b);
        }
    }

    controller:

      @RequestMapping(value = "/captcha")
        @ResponseBody
        public String imagecode(HttpServletRequest request, HttpServletResponse response) throws Exception {
            response.setDateHeader("Expires", 0);
            response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            response.addHeader("Cache-Control", "post-check=0, pre-check=0");
            response.setHeader("Pragma", "no-cache");
            response.setContentType("image/jpeg");
    
            OutputStream os = response.getOutputStream();
            //返回验证码和图片的map
            Map<String, Object> map = Captcha.getImageCode(86, 37, os);
            String simpleCaptcha = "simpleCaptcha";
            request.getSession().setAttribute("simpleCaptcha", map.get("strEnsure").toString().toLowerCase());
            request.getSession().setAttribute("codeTime", new Date().getTime());
            try {
                ImageIO.write((BufferedImage) map.get("image"), "jpg", os);
            } catch (IOException e) {
                return "";
            } finally {
                if (os != null) {
                    os.flush();
                    os.close();
                }
            }
            return null;
        }
    
    
    
    
            @RequestMapping(value = "/verify")
            @ResponseBody
            public String checkcode(HttpServletRequest request,
                                    HttpSession session,
                                    String checkCode) throws Exception {
    
                checkCode=(String) request.getSession().getAttribute("simpleCaptcha");
    
                // 获得验证码对象
               /* Object cko = session.getAttribute("simpleCaptcha");*/
                String cko = request.getParameter("checkcode01");
    
                if (cko == null ||cko=="") {
                    request.setAttribute("errorMsg", "请输入验证码!");
                    System.out.println("验证码是空格的啊");
                    return "请输入验证码!";
                }
                String captcha = cko.toString();//文本框输入的验证码
                // 判断验证码输入是否正确
                Date now = new Date();
                Long codeTime = Long.valueOf(session.getAttribute("codeTime") + "");
                if (StringUtils.isEmpty(checkCode) || captcha == null || !(checkCode.equalsIgnoreCase(captcha))) {
                    request.setAttribute("errorMsg", "验证码错误!");
                    System.out.println("验证码错的呀");
                    return "验证码错误,请重新输入!";
    
                    // 验证码有效时长为1分钟
    
                } else if ((now.getTime() - codeTime) / 1000 / 60 > 1) {
                    request.setAttribute("errorMsg", "验证码已失效,请重新输入!");
                    System.out.println("验证码时间太长了");
                    return "验证码已失效,请重新输入!";
                } else {
    
                    // 在这里可以处理自己需要的事务,比如验证登陆等
                    System.out.println("验证码输入正确");
                    return "验证通过!";
                }
            }

    架构:

    解释:

    首先来看工具类:  工具类反正像我这种我是看不懂的,   如果你也看不懂 需要关注工具类的几个点就可以了。 他这个工具类已经写好了,我们需要关心的就是这个验证码图片中的数字。

    可能你不知道怎么去map集合中拿出来使用。  不用担心,他在controller中的代码已经拿出来了。 

     我们主要在下面这个分支做操作。

    页面:

    文本框:

    验证码图片:

  • 相关阅读:
    STM32 F4 DAC DMA Waveform Generator
    STM32 F4 General-purpose Timers for Periodic Interrupts
    Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
    Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块
    查看SQL Server服务运行帐户和SQL Server的所有注册表项
    Pycharm使用技巧(转载)
    SQL Server 2014内存优化表的使用场景
    Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
    Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
    Python第六天 类型转换
  • 原文地址:https://www.cnblogs.com/java-263/p/10778529.html
Copyright © 2011-2022 走看看