zoukankan      html  css  js  c++  java
  • java图形验证码生成工具类及web页面校验验证码

    最近做验证码,参考网上案例,发现有不少问题,特意进行了修改和完善。

    验证码生成器:

    1. import javax.imageio.ImageIO;    
    2. import java.awt.*;    
    3. import java.awt.image.BufferedImage;    
    4. import java.io.FileOutputStream;    
    5. import java.io.IOException;    
    6. import java.io.OutputStream;    
    7. import java.util.Date;    
    8. import java.util.Random;    
    9.     
    10. /**   
    11.  * 验证码生成器   
    12.  *   
    13.  * @author    
    14.  */    
    15. public class ValidateCode {    
    16.     // 图片的宽度。    
    17.     private int width = 160;    
    18.     // 图片的高度。    
    19.     private int height = 40;    
    20.     // 验证码字符个数    
    21.     private int codeCount = 5;    
    22.     // 验证码干扰线数    
    23.     private int lineCount = 150;    
    24.     // 验证码    
    25.     private String code = null;    
    26.     // 验证码图片Buffer    
    27.     private BufferedImage buffImg = null;    
    28.     
    29.     // 验证码范围,去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了)    
    30.     private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',    
    31.             'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',    
    32.             'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'};    
    33.     
    34.     /**   
    35.      * 默认构造函数,设置默认参数   
    36.      */    
    37.     public ValidateCode() {    
    38.         this.createCode();    
    39.     }    
    40.     
    41.     /**   
    42.      * @param width  图片宽   
    43.      * @param height 图片高   
    44.      */    
    45.     public ValidateCode(int width, int height) {    
    46.         this.width = width;    
    47.         this.height = height;    
    48.         this.createCode();    
    49.     }    
    50.     
    51.     /**   
    52.      * @param width     图片宽   
    53.      * @param height    图片高   
    54.      * @param codeCount 字符个数   
    55.      * @param lineCount 干扰线条数   
    56.      */    
    57.     public ValidateCode(int width, int height, int codeCount, int lineCount) {    
    58.         this.width = width;    
    59.         this.height = height;    
    60.         this.codeCount = codeCount;    
    61.         this.lineCount = lineCount;    
    62.         this.createCode();    
    63.     }    
    64.     
    65.     public void createCode() {    
    66.         int x = 0fontHeight = 0codeY = 0;    
    67.         int red = 0green = 0blue = 0;    
    68.     
    69.         x = width / (codeCount + 2);//每个字符的宽度(左右各空出一个字符)    
    70.         fontHeight = height - 2;//字体的高度    
    71.         codeY = height - 4;    
    72.     
    73.         // 图像buffer    
    74.         buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);    
    75.         Graphics2D g = buffImg.createGraphics();    
    76.         // 生成随机数    
    77.         Random random = new Random();    
    78.         // 将图像填充为白色    
    79.         g.setColor(Color.WHITE);    
    80.         g.fillRect(0, 0, width, height);    
    81.         // 创建字体,可以修改为其它的    
    82.         Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);    
    83. //        Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight);    
    84.         g.setFont(font);    
    85.     
    86.         for (int i = 0; i < lineCount; i++) {    
    87.             // 设置随机开始和结束坐标    
    88.             int xs = random.nextInt(width);//x坐标开始    
    89.             int ys = random.nextInt(height);//y坐标开始    
    90.             int xe = xs + random.nextInt(width / 8);//x坐标结束    
    91.             int ye = ys + random.nextInt(height / 8);//y坐标结束    
    92.     
    93.             // 产生随机的颜色值,让输出的每个干扰线的颜色值都将不同。    
    94.             red = random.nextInt(255);    
    95.             green = random.nextInt(255);    
    96.             blue = random.nextInt(255);    
    97.             g.setColor(new Color(red, green, blue));    
    98.             g.drawLine(xs, ys, xe, ye);    
    99.         }    
    100.     
    101.         // randomCode记录随机产生的验证码    
    102.         StringBuffer randomCode = new StringBuffer();    
    103.         // 随机产生codeCount个字符的验证码。    
    104.         for (int i = 0; i < codeCount; i++) {    
    105.             String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);    
    106.             // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。    
    107.             red = random.nextInt(255);    
    108.             green = random.nextInt(255);    
    109.             blue = random.nextInt(255);    
    110.             g.setColor(new Color(red, green, blue));    
    111.             g.drawString(strRand, (i + 1) * x, codeY);    
    112.             // 将产生的四个随机数组合在一起。    
    113.             randomCode.append(strRand);    
    114.         }    
    115.         // 将四位数字的验证码保存到Session中。    
    116.         code = randomCode.toString();    
    117.     }    
    118.     
    119.     public void write(String path) throws IOException {    
    120.         OutputStream sos = new FileOutputStream(path);    
    121.         this.write(sos);    
    122.     }    
    123.     
    124.     public void write(OutputStream sos) throws IOException {    
    125.         ImageIO.write(buffImg, "png", sos);    
    126.         sos.close();    
    127.     }    
    128.     
    129.     public BufferedImage getBuffImg() {    
    130.         return buffImg;    
    131.     }    
    132.     
    133.     public String getCode() {    
    134.         return code;    
    135.     }    
    136.     
    137.     /**   
    138.      * 测试函数,默认生成到d盘   
    139.      * @param args   
    140.      */    
    141.     public static void main(String[] args) {    
    142.         ValidateCode vCode = new ValidateCode(160,40,5,150);    
    143.         try {    
    144.             String path="D:/"+new Date().getTime()+".png";    
    145.             System.out.println(vCode.getCode()+" >"+path);    
    146.             vCode.write(path);    
    147.         } catch (IOException e) {    
    148.             e.printStackTrace();    
    149.         }    
    150.     }    
    151. }    

    下面是页面JS调用验证码

    [javascript] view plain copy
    print?
    1. // 刷新图片    
    2.         function changeImg() {    
    3.             var imgSrc = $("#imgObj");    
    4.             var url = imgSrc.attr("src");   
    5.             imgSrc.attr("src", changeUrl(url));    
    6.         }    
    7.         //为了使每次生成图片不一致,即不让浏览器读缓存,所以需要加上时间戳    
    8.         function changeUrl(url) {    
    9.             var timestamp = (new Date()).valueOf();    
    10.             var index = url.indexOf("?");  
    11.             console.log(index);   
    12.             if (index > 0) {    
    13.                 url = url.substring(0, url.indexOf("?"));    
    14.             }  
    15.             console.log(url);  
    16.             if ((url.indexOf("&") > 0)) {    
    17.                 url = url + "×tamp=" + timestamp;    
    18.                 console.log(url);  
    19.             } else {    
    20.                 url = url + "?timestamp=" + timestamp;  
    21.                 console.log(url);  
    22.                 }    
    23.             return url;    
    24.         }  

    下面是controller层输出验证码

    1. /  
    2.   响应验证码页面  
    3.   @return  
    4.  */    
    5. @RequestMapping(value="/validateCode")    
    6. public String validateCode(HttpServletRequest request,HttpServletResponse response) throws Exception{    
    7.     // 设置响应的类型格式为图片格式    
    8.     response.setContentType("image/jpeg");    
    9.     //禁止图像缓存。    
    10.     response.setHeader("Pragma""no-cache");    
    11.     response.setHeader("Cache-Control""no-cache");    
    12.     response.setDateHeader("Expires"0);    
    13.     
    14.     HttpSession session = request.getSession();    
    15.     
    16.     ValidateCode vCode = new ValidateCode(120,40,5,100);    
    17.     session.setAttribute("code", vCode.getCode());    
    18.     vCode.write(response.getOutputStream());    
    19.     return null;    
    20. }    

    下面是controller层验证验证码输入是否正确

    1. String code = request.getParameter("code");    
    2. HttpSession session = request.getSession();    
    3. String sessionCode = (String) session.getAttribute("code");    
    4. if (!StringUtils.equalsIgnoreCase(code, sessionCode)) {  //忽略验证码大小写    
    5.     throw new RuntimeException("验证码对应不上code=" + code + "  sessionCode=" + sessionCode);    
    6. }   



查看全文
  • 相关阅读:
    210111做个期望值低的人
    error_1 springboot `com.mysql.jdbc.Driver'问题
    error_2 springboot mysql时区设置
    17_springboot Restful风格
    15_JSON springboot
    13_springboot文件上传
    12_springboot myBatis crud
    11_springboot JPA crud
    Swagger导出MarkDown
    Docker 使用中的一些问题
  • 原文地址:https://www.cnblogs.com/jpfss/p/8444116.html
  • Copyright © 2011-2022 走看看