• 轻量级验证码生成插件webutil-licenseImage源码与实例应用


    webutil-licenseImage 插件内置4种验证码样式,支持用户扩展.自定义样式实现简单验证码.

    源码脱管地址http://code.google.com/p/licenseimage/

    Jar包下载地址: http://files.cnblogs.com/dennisit/Java%E9%AA%8C%E8%AF%81%E7%A0%81%E6%8F%92%E4%BB%B6.rar

     

    项目结构图:

    说明:

    ResourceUtil类为获取包内资源服务
    LicenseImage用来生成验证码

    思路: 通过获取验证码图片资源,创建BufferedImage图片对象,然后获取该对象的Graphics2D操作类,使用Graphics2D绘制背景图,绘制随机生成的字码,绘制干扰线,将结果封装成Map集合,mapkey值用来做为session中判断的依据,MapkeyBufferedImage对象,用于展示给前台输出.

     

    核心代码如下:

    ResourceUtil类

    package org.pudp.util;
    import java.net.URL;
    import java.net.URLClassLoader;
    /**
     * 类说明:
     *
     * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 
     *
     * org.pudp.util.Resource.java
     *
     */
    public class ResourceUtil {
    
        /**
         * 获取资源的URL路径
         *
         * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 下午09:33:07
         *                
         * @param paramString
         *             验证码图片所在的包的相对路径
         * @return
         *             验证码所在的URL
         */
        public static URL getResourceUrl(String paramString){
            return ((URLClassLoader)ResourceUtil.class.getClassLoader()).getResource(paramString);
        }
    
        /**
         * 获取资源的串值路径
         *
         * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 下午06:09:17
         *                
         * @param paramString
         *                     验证码图片所在的包的相对路径
         * @return
         *             验证码所在的串值地址
         */
        public static String getResourcePath(String paramString){
            return Thread.currentThread().getContextClassLoader().getResource(paramString).getPath(); 
        }
        
    }

    生成验证码的核心类

    package org.pudp.util.license;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.geom.AffineTransform;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Random;
    import javax.imageio.ImageIO;
    
    import org.pudp.util.ResourceUtil;
    
    
    /**
     * 类说明: 验证码工具
     *
     * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 
     *
     * org.pudp.util.license.LicenseImage.java
     *
     */
    
    public class LicenseImage {
        
        public static final Integer TYPE1 = 1;        //样式一
        public static final Integer TYPE2 = 2;        //样式二
        public static final Integer TYPE3 = 3;        //样式三
        public static final Integer TYPE4 = 4;        //样式四
        
        public static final int DEF_NUM = 4;            //验证码上的字符个数
        public static final int DEF_LINES = 3;             //干扰线条数
        public static final int DEF_WIDTH = 150;        //验证码图片宽
        public static final int DEF_HEIGHT = 50;        //验证码图片高
        public static final int DEF_FONT_SIZE = 24;        //验证码上字体大小
            
        private int num;                    //验证码上的字符个数
        private int width ;                    //验证码图片宽
        private int height ;                //验证码图片高
        private int fontSize ;                //验证码上字体大小
        private int lines ;                    //干扰线条数
     
        
        private static final String[] chars = { "0", "1", "2", "3", "4", "5", "6",
            "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I" };
        
        public LicenseImage(){
            this(DEF_WIDTH, DEF_HEIGHT, DEF_FONT_SIZE, DEF_NUM, DEF_LINES);
        }
        
        /**
         * 自定义验证码的宽度与高度
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         */
        public LicenseImage(int width,int height){
            if(width<0 || height<0){
                this.width = LicenseImage.DEF_WIDTH;
                this.height = LicenseImage.DEF_HEIGHT;
            }else{
                this.width = width;
                this.height = height;
            }
            this.num = LicenseImage.DEF_NUM;
            this.fontSize = LicenseImage.DEF_FONT_SIZE;
            this.lines = LicenseImage.DEF_LINES;
        }
        
        /**
         * 自定义验证码的宽度和高度,以及字体大小
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         * @param fontSize
         *                     验证码字体大小
         */
        public LicenseImage(int width,int height,int fontSize){
            this(width, height);
            this.fontSize = fontSize;
            this.num = LicenseImage.DEF_NUM;
            this.lines = LicenseImage.DEF_LINES;
        }
     
        /**
         * 自定义验证码的宽度和高度,以及字体大小
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         * @param fontSize
         *                     验证码字体大小
         * 
         * @param size
         *                     验证码上字体个数
         */
        public LicenseImage(int width,int height,int fontSize,int num){
            this(width, height,fontSize);
            if(num <0){
                this.num = LicenseImage.DEF_NUM;
            }else{
                this.num = num;
            }
        
            this.lines = LicenseImage.DEF_LINES;
        }
        
        /**
         * 自定义验证码的宽度和高度,以及字体大小
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         * @param fontSize
         *                     验证码字体大小
         * @param size
         *                     验证码上字体个数
         * 
         * @param lines
         *                     验证码上的干扰线条数目
         */
        
        public LicenseImage(int width,int height,int fontSize,int num,int lines){
            this(width, height,fontSize,num);
            this.lines = lines;
        }
     
        
        /**
         * 
         * 生成验证码,验证码图片由用户自己定义
         *
         * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 下午08:13:53
         *                
         * @param backgroundPath
         *                     用户自定义的验证码的背景图片
         * @return
         *                     验证码生成后的封装对象
         */
        public Map<String,BufferedImage> createImage(String backgroundPath){
            //保存产生验证码真实值的串
            StringBuffer buffer = new StringBuffer();    
            //自定义图片对象
            BufferedImage image = new BufferedImage(this.width,this.height,BufferedImage.TYPE_INT_RGB);
            Map<String,BufferedImage> map = new HashMap<String,BufferedImage>();
            Graphics2D graphics = (Graphics2D) image.createGraphics();
            graphics.setColor(Color.WHITE);
            // 初始化背景图片
            try {
                Image bgImage = ImageIO.read(ResourceUtil.getResourceUrl(backgroundPath));
                graphics.drawImage(bgImage,0,0,this.width,this.height,null);
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            Random random = new Random();
            //画随机字符
            for(int i=0; i<this.num; i++){
                //随即获取定义字符集中的一个元素
                int rand = random.nextInt(chars.length);
                graphics.setColor(randomColor());
                graphics.setFont(new Font("Times New Roman",Font.BOLD+Font.ITALIC,this.fontSize));
                /** **随机缩放文字并将文字旋转指定角度* start*/
                Graphics2D g2d_word = (Graphics2D) graphics;
                AffineTransform trans = new AffineTransform();
                trans.rotate(random.nextInt(10) * 3.14 / 90, 13 * i + 8, 7);
                // 缩放文字
                float scaleSize = random.nextFloat() +0.8f;
                if (scaleSize > 1f){
                    scaleSize = 1f;
                }    
                trans.scale(scaleSize, scaleSize);
                g2d_word.setTransform(trans);
                /** **随机缩放文字并将文字旋转指定角度* end*/
                graphics.drawString(chars[rand],(this.num*2)+(i)*this.width/this.num , this.height/2);
                buffer.append(chars[rand]); //将生成的字符串存入到buffer中,将来获取时用于跟用户输入的值比较
            }
            //画干扰线
            for(int i=1;i<=this.lines;i++){
                graphics.setColor(randomColor());
                graphics.drawLine(random.nextInt(this.width), random.nextInt(this.height),
                        random.nextInt(this.width),random.nextInt(this.height));
                if(i==this.lines){
                    Font font = new Font("Times New Roman",Font.PLAIN, this.fontSize-5);
                    graphics.setFont(font);
                    graphics.setColor(Color.GRAY);
                }
            }
            //画一条折线        
            /*
            BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL);    //创建一个供画笔选择线条粗细的对象
            graphics.setStroke(bs);                    //改变线条的粗细
            graphics.setColor(randomColor());        //设置当前颜色为预定义颜色中的深灰色
            int[] xPoints=new int[3];
            int[] yPoints=new int[3];
            for(int j=0;j<3;j++){
                xPoints[j]=random.nextInt(WIDTH - 1);
                yPoints[j]=random.nextInt(HEIGHT - 1);
            }
            graphics.drawPolyline(xPoints, yPoints,3);
            */
            map.put(buffer.toString(), image);
            return map;
        }
        
        
        /**
         * 
         * 使用系统默认样式
         * 
         * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 下午08:06:22
         *                
         * @param type
         *                 工具内置的类型,用户使用该类型即可用内置的样式生成验证码
         * @return
         *                 Map<验证码的值,验证码的图片>
         */
        public  Map<String,BufferedImage> createImage(int type){
            return createImage("org/pudp/util/license/resources/yzm"+type+".gif");
        }
        
        
        /**
         * 随即产生颜色
         *
         * @author <a href='mailto:dennisit@163.com'>Cn.苏若年(En.dennisit)</a> Copy Right since 2013-9-16 下午08:04:08
         *                
         * @return
         *            <code>Color对象</code>
         */
        public static Color randomColor(){
            Random random = new Random();
            Color color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
            return color;
        }
        
    }


    实例应用

    创建servlet

        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doPost(request, response);
        }
    
        public void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 禁止图像缓存。
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setContentType("image/jpeg");
            
            //使用验证码工具生成验证码
            LicenseImage licenseImage = new LicenseImage();
            //使用验证码工具内置样式
            Map<String,BufferedImage> licenseImg = licenseImage.createImage(LicenseImage.TYPE1);
            //获取map集合中的值
            String key =  (String)licenseImg.keySet().iterator().next();
            //将验证码的key放入session中
            //SessionUtil.session(request).setAttribute(CommonConstant.LicenseImageKey, key);
            System.out.println("session中的验证码值为:" + key);
            //获取map集合中的图片对象
            BufferedImage buffImg = licenseImg.get(key);
            ServletOutputStream out = response.getOutputStream();
            ImageIO.write(buffImg, "jpeg", out);
            out.close();
        }

    内置样式一效果图

    使用工具内置的样式生成验证码代码,licenseImage.createImage(int type)方法,传递系统内置的4种样式即可生成验证码

            //使用验证码工具生成验证码
            LicenseImage licenseImage = new LicenseImage();
            //使用验证码工具内置样式
            Map<String,BufferedImage> licenseImg = licenseImage.createImage(LicenseImage.TYPE1);

    系统后台为我们打印出了session中存放的验证码的串值如下:



    开发者自定义验证码,构造自定义参数说明如下

       /**
         * 自定义验证码的宽度与高度
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         */
        public LicenseImage(int width,int height){
            this.width = width;
            this.height = height;
            this.num = LicenseImage.DEF_NUM;
            this.fontSize = LicenseImage.DEF_FONT_SIZE;
            this.lines = LicenseImage.DEF_LINES;
        }
        
        /**
         * 自定义验证码的宽度和高度,以及字体大小
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         * @param fontSize
         *                     验证码字体大小
         */
        public LicenseImage(int width,int height,int fontSize){
            this(width, height);
            this.fontSize = fontSize;
            this.num = LicenseImage.DEF_NUM;
            this.lines = LicenseImage.DEF_LINES;
        }
     
        /**
         * 自定义验证码的宽度和高度,以及字体大小
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         * @param fontSize
         *                     验证码字体大小
         * 
         * @param size
         *                     验证码上字体个数
         */
        public LicenseImage(int width,int height,int fontSize,int num){
            this(width, height,fontSize);
            this.num = num;
            this.lines = LicenseImage.DEF_LINES;
        }
        
        /**
         * 自定义验证码的宽度和高度,以及字体大小
         * @param width
         *                     验证码的宽度
         * @param height
         *                     验证码的高度
         * @param fontSize
         *                     验证码字体大小
         * @param size
         *                     验证码上字体个数
         * 
         * @param lines
         *                     验证码上的干扰线条数目
         */
        
        public LicenseImage(int width,int height,int fontSize,int num,int lines){
            this(width, height,fontSize,num);
            this.lines = lines;
        }
    View Code


    自定义实例应用

    //使用验证码工具提供的构造参数自定义相应的参数值
        LicenseImage licenseImage = new LicenseImage(120,50,18,5,5);
        //指定自定义背景包内的相对路径
        Map<String,BufferedImage> licenseImg = licenseImage.createImage("definebk.png");

    如果自定义图片在com.define包下,传递的串值参数为

        Map<String,BufferedImage> licenseImg = licenseImage.createImage("com/define/definebk.png");

    自定义实例效果图


    内置几种样式:

    应用说明,见jar包里边的readme.txt文件

     

    转载请注明出处:[http://www.cnblogs.com/dennisit/p/3325871.html]

    在线交谈

  • 相关阅读:
    weblogic weak_password 复现
    redis 4-unacc 复现
    Django debug page XSS漏洞(CVE-2017-12794)复现
    (CVE-2016-4437)Apache Shiro <=1.2.4 反序列化漏洞复现
    Apache SSI 远程命令执行漏洞复现
    Apache HTTPD 未知后缀解析漏洞复现
    s2-005复现
    05 跨站请求伪造漏洞CSRF
    安全大面
    JAVA基础学习day03--流程控制语句
  • 原文地址:https://www.cnblogs.com/dennisit/p/3325871.html
Copyright © 2020-2023  润新知