zoukankan      html  css  js  c++  java
  • java实现图片验证码

    一、验证码生成类

      1 package hbi.tech.utils;
      2 import javax.imageio.ImageIO;
      3 import java.awt.*;
      4 import java.awt.image.BufferedImage;
      5 import java.io.ByteArrayInputStream;
      6 import java.io.FileOutputStream;
      7 import java.io.IOException;
      8 import java.io.OutputStream;
      9 import java.util.Random;
     10 
     11 /**
     12  * 验证码生成器
     13  * 
     14  */
     15 public class SCaptcha {
     16     // 图片的宽度。
     17     private int width = 120;
     18     // 图片的高度。
     19     private int height = 40;
     20     // 验证码字符个数
     21     private int codeCount = 4;
     22     // 验证码干扰线数
     23     private int lineCount = 50;
     24     // 验证码
     25     private String code = null;
     26     // 验证码图片Buffer
     27     private BufferedImage buffImg = null;
     28 
     29     private char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'P', 'Q', 'R',
     30             'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9' };
     31     // 生成随机数
     32     private Random random = new Random();
     33 
     34     public SCaptcha() {
     35         this.createCode();
     36     }
     37 
     38     /**
     39      * 
     40      * @param width 图片宽
     41      * @param height 图片高
     42      */
     43     public SCaptcha(int width, int height) {
     44         this.width = width;
     45         this.height = height;
     46         this.createCode();
     47     }
     48 
     49     /**
     50      * 
     51      * @param width 图片宽
     52      * @param height 图片高
     53      * @param codeCount 字符个数
     54      * @param lineCount 干扰线条数
     55      */
     56     public SCaptcha(int width, int height, int codeCount, int lineCount) {
     57         this.width = width;
     58         this.height = height;
     59         this.codeCount = codeCount;
     60         this.lineCount = lineCount;
     61         this.createCode();
     62     }
     63 
     64     public void createCode() {
     65         int codeX = 0;
     66         int fontHeight = 0;
     67         fontHeight = height - 5;// 字体的高度
     68         codeX = width / (codeCount + 3);// 每个字符的宽度
     69 
     70         // 图像buffer
     71         buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
     72         Graphics2D g = buffImg.createGraphics();
     73 
     74         // 将图像填充为白色
     75         g.setColor(Color.WHITE);
     76         g.fillRect(0, 0, width, height);
     77 
     78         // 创建字体
     79         ImgFontByte imgFont = new ImgFontByte();
     80         Font font = imgFont.getFont(fontHeight);
     81         g.setFont(font);
     82 
     83         StringBuffer randomCode = new StringBuffer();
     84         // 随机产生验证码字符
     85         for (int i = 0; i < codeCount; i++) {
     86             String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
     87             // 设置字体颜色
     88             g.setColor(getRandomColor());
     89             // 设置字体位置
     90             g.drawString(strRand, (i + 1) * codeX, getRandomNumber(height / 2) + 25);
     91             randomCode.append(strRand);
     92         }
     93         code = randomCode.toString();
     94     }
     95 
     96     /** 获取随机颜色 */
     97     private Color getRandomColor() {
     98         int r = getRandomNumber(255);
     99         int g = getRandomNumber(255);
    100         int b = getRandomNumber(255);
    101         return new Color(r, g, b);
    102     }
    103 
    104     /** 获取随机数 */
    105     private int getRandomNumber(int number) {
    106         return random.nextInt(number);
    107     }
    108 
    109     public void write(String path) throws IOException {
    110         OutputStream sos = new FileOutputStream(path);
    111         this.write(sos);
    112     }
    113 
    114     public void write(OutputStream sos) throws IOException {
    115         ImageIO.write(buffImg, "png", sos);
    116         sos.close();
    117     }
    118 
    119     public BufferedImage getBuffImg() {
    120         return buffImg;
    121     }
    122 
    123     public String getCode() {
    124         return code;
    125     }
    126 
    127     /** 字体样式类 */
    128     class ImgFontByte {
    129         public Font getFont(int fontHeight) {
    130             try {
    131                 Font baseFont = Font.createFont(Font.HANGING_BASELINE, new ByteArrayInputStream(
    132                         hex2byte(getFontByteStr())));
    133                 return baseFont.deriveFont(Font.PLAIN, fontHeight);
    134             } catch (Exception e) {
    135                 return new Font("Arial", Font.PLAIN, fontHeight);
    136             }
    137         }
    138 
    139         private byte[] hex2byte(String str) {
    140             if (str == null)
    141                 return null;
    142             str = str.trim();
    143             int len = str.length();
    144             if (len == 0 || len % 2 == 1)
    145                 return null;
    146 
    147             byte[] b = new byte[len / 2];
    148             try {
    149                 for (int i = 0; i < str.length(); i += 2) {
    150                     b[i / 2] = (byte) Integer.decode("0x" + str.substring(i, i + 2)).intValue();
    151                 }
    152                 return b;
    153             } catch (Exception e) {
    154                 return null;
    155             }
    156         }
    157 
    158         // 字体文件的十六进制字符串
    159         private String getFontByteStr() {
    160             //防止报字符串长度过长错误,改为从配置文件读取
    161             return ReadFontByteProperties.getFontByteStr();
    162         }
    163     }
    164 }

    二、读取字体文件类

     1 package hbi.tech.utils;
     2 import java.io.InputStream;
     3 import java.util.Properties;
     4 public class ReadFontByteProperties {
     5     static private String fontByteStr = null;
     6     static {
     7         loads();
     8     }
     9     synchronized static public void loads() {
    10         if (fontByteStr == null) {
    11             InputStream is = ReadFontByteProperties.class.getResourceAsStream("/fontByte.properties");
    12             Properties dbproperties = new Properties();
    13             try {
    14                 dbproperties.load(is);
    15                 fontByteStr = dbproperties.getProperty("fontByteStr").toString();
    16             } catch (Exception e) {
    17                 //System.err.println("不能读取属性文件. " + "请确保fontByte.properties在CLASSPATH指定的路径中");
    18             }
    19         }
    20     }
    21     public static String getFontByteStr() {
    22         if (fontByteStr == null)
    23             loads();
    24         return fontByteStr;
    25     }
    26 }

    三、生成验证码接口

     1    /**
     2      * @author jiaqing.xu@hand-china.com
     3      * @date 2017/8/23
     4      * @description 生成图片验证码
     5      */
     6     @RequestMapping(value = "/userInfo/verification", method = {RequestMethod.POST, RequestMethod.GET})
     7     @ResponseBody
     8     public void verification(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
     9         // 设置响应的类型格式为图片格式
    10         response.setContentType("image/jpeg");
    11         // 禁止图像缓存。
    12         response.setHeader("Pragma", "no-cache");
    13         response.setHeader("Cache-Control", "no-cache");
    14         response.setDateHeader("Expires", 0);
    15         //实例生成验证码对象
    16         SCaptcha instance = new SCaptcha();
    17         //将验证码存入session
    18         session.setAttribute("verification", instance.getCode());
    19         //向页面输出验证码图片
    20         instance.write(response.getOutputStream());
    21     }

    将生成的验证码图片存在session中,当用户登录时即可和用户输入的验证码的值进行判断,如果验证相同,则进行后续操作。

  • 相关阅读:
    css3--简单的加载动画
    background--详解(背景图片根据屏幕的自适应)
    css--两行显示省略号兼容火狐浏览器
    tortoisegit--无法commit
    vim--学习
    JavaScript--数据结构与算法之图
    JSONP
    数据结构--只用位运算实现加减乘除操作
    剑指offer——不用加减乘除做加法
    shop--10.前端展示系统--首页展示(后台)
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/7598542.html
Copyright © 2011-2022 走看看