验证码是很多系统都需要的,今天搞了一下午终于把验证码的功能实现了,可以显示三种不同类型的验证码而不是单独一种,显示效果如下图所示:

* 第一种:简单验证码,4位随机数字 :

* 第二种:英文字符加数字的验证码 :

* 第三种:像铁路订票系统一样的验证码,肆+?=21

下面是实现的验证码类

Java代码  
  1. package com.base.util;
  2. import java.awt.Color;
  3. import java.awt.Font;
  4. import java.awt.Graphics;
  5. import java.awt.image.BufferedImage;
  6. import java.io.ByteArrayInputStream;
  7. import java.io.ByteArrayOutputStream;
  8. import java.util.Random;
  9. import javax.imageio.ImageIO;
  10. import javax.imageio.stream.ImageOutputStream;
  11. /**
  12. * 验证码类,主要生成几种不同类型的验证码
  13. * 第一种:简单验证码,4位随机数字
  14. * 第二种:英文字符加数字的验证码
  15. * 第三种:像铁路订票系统一样的验证码,肆+?=21
  16. *
  17. * @author 李朋飞
  18. *
  19. */
  20. public class VerificationCodeUtil {
  21. private ByteArrayInputStream image;// 图像
  22. private String str;// 验证码
  23. private static final int WIDTH = 80;
  24. private static final int HEIGHT = 20;
  25. public static void main(String[] arg) {
  26. VerificationCodeUtil vcu = VerificationCodeUtil.Instance();
  27. System.err.println(vcu.getVerificationCodeValue());
  28. }
  29. /**
  30. * 功能:获取一个验证码类的实例
  31. *
  32. * @return
  33. */
  34. public static VerificationCodeUtil Instance() {
  35. return new VerificationCodeUtil();
  36. }
  37. private VerificationCodeUtil() {
  38. BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
  39. BufferedImage.TYPE_INT_RGB);
  40. int randomNum = new Random().nextInt(3);
  41. if (randomNum == 0) {
  42. initNumVerificationCode(image);
  43. } else if (randomNum == 1) {
  44. initLetterAndNumVerificationCode(image);
  45. } else {
  46. initChinesePlusNumVerificationCode(image);
  47. }
  48. }
  49. /**
  50. * 功能:设置第一种验证码的属性
  51. */
  52. public void initNumVerificationCode(BufferedImage image) {
  53. Random random = new Random(); // 生成随机类
  54. Graphics g = initImage(image, random);
  55. String sRand = "";
  56. for (int i = 0; i < 4; i++) {
  57. String rand = String.valueOf(random.nextInt(10));
  58. sRand += rand;
  59. // 将认证码显示到图象中
  60. g.setColor(new Color(20 + random.nextInt(110), 20 + random
  61. .nextInt(110), 20 + random.nextInt(110)));
  62. // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
  63. g.drawString(rand, 13 * i + 6, 16);
  64. }
  65. this.setStr(sRand);/* 赋值验证码 */
  66. // 图象生效
  67. g.dispose();
  68. this.setImage(drawImage(image));
  69. }
  70. /**
  71. * 功能:设置第二种验证码属性
  72. */
  73. public void initLetterAndNumVerificationCode(BufferedImage image) {
  74. Random random = new Random(); // 生成随机类
  75. Graphics g = initImage(image, random);
  76. String[] letter = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
  77. "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
  78. "W", "X", "Y", "Z" };
  79. String sRand = "";
  80. for (int i = 0; i < 4; i++) {
  81. String tempRand = "";
  82. if (random.nextBoolean()) {
  83. tempRand = String.valueOf(random.nextInt(10));
  84. } else {
  85. tempRand = letter[random.nextInt(25)];
  86. if (random.nextBoolean()) {// 随机将该字母变成小写
  87. tempRand = tempRand.toLowerCase();
  88. }
  89. }
  90. sRand += tempRand;
  91. g.setColor(new Color(20 + random.nextInt(10), 20 + random
  92. .nextInt(110), 20 + random.nextInt(110)));
  93. g.drawString(tempRand, 13 * i + 6, 16);
  94. }
  95. this.setStr(sRand);/* 赋值验证码 */
  96. g.dispose(); // 图象生效
  97. this.setImage(drawImage(image));
  98. }
  99. /**
  100. * 功能:设置第三种验证码属性 即:肆+?=24
  101. */
  102. public void initChinesePlusNumVerificationCode(BufferedImage image) {
  103. String[] cn = { "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾" };
  104. Random random = new Random(); // 生成随机类
  105. Graphics g = initImage(image, random);
  106. int x = random.nextInt(10) + 1;
  107. int y = random.nextInt(30);
  108. this.setStr(String.valueOf(y));
  109. g.setFont(new Font("楷体", Font.PLAIN, 14));// 设定字体
  110. g.setColor(new Color(20 + random.nextInt(10), 20 + random.nextInt(110),
  111. 20 + random.nextInt(110)));
  112. g.drawString(cn[x - 1], 1 * 1 + 6, 16);
  113. g.drawString("+", 22, 16);
  114. g.drawString("?", 35, 16);
  115. g.drawString("=", 48, 16);
  116. g.drawString(String.valueOf(x + y), 61, 16);
  117. g.dispose(); // 图象生效
  118. this.setImage(drawImage(image));
  119. }
  120. public Graphics initImage(BufferedImage image, Random random) {
  121. Graphics g = image.getGraphics(); // 获取图形上下文
  122. g.setColor(getRandColor(200, 250));// 设定背景色
  123. g.fillRect(0, 0, WIDTH, HEIGHT);
  124. g.setFont(new Font("Times New Roman", Font.PLAIN, 14));// 设定字体
  125. g.setColor(getRandColor(160, 200)); // 随机产生165条干扰线,使图象中的认证码不易被其它程序探测到
  126. for (int i = 0; i < 165; i++) {
  127. int x = random.nextInt(WIDTH);
  128. int y = random.nextInt(HEIGHT);
  129. int xl = random.nextInt(12);
  130. int yl = random.nextInt(12);
  131. g.drawLine(x, y, x + xl, y + yl);
  132. }
  133. return g;
  134. }
  135. public ByteArrayInputStream drawImage(BufferedImage image) {
  136. ByteArrayInputStream input = null;
  137. ByteArrayOutputStream output = new ByteArrayOutputStream();
  138. try {
  139. ImageOutputStream imageOut = ImageIO
  140. .createImageOutputStream(output);
  141. ImageIO.write(image, "JPEG", imageOut);
  142. imageOut.close();
  143. input = new ByteArrayInputStream(output.toByteArray());
  144. } catch (Exception e) {
  145. System.out.println("验证码图片产生出现错误:" + e.toString());
  146. }
  147. return input;
  148. }
  149. /*
  150. * 功能:给定范围获得随机颜色
  151. */
  152. private Color getRandColor(int fc, int bc) {
  153. Random random = new Random();
  154. if (fc > 255)
  155. fc = 255;
  156. if (bc > 255)
  157. bc = 255;
  158. int r = fc + random.nextInt(bc - fc);
  159. int g = fc + random.nextInt(bc - fc);
  160. int b = fc + random.nextInt(bc - fc);
  161. return new Color(r, g, b);
  162. }
  163. /**
  164. * 功能:获取验证码的字符串值
  165. *
  166. * @return
  167. */
  168. public String getVerificationCodeValue() {
  169. return this.getStr();
  170. }
  171. /**
  172. * 功能:取得验证码图片
  173. *
  174. * @return
  175. */
  176. public ByteArrayInputStream getImage() {
  177. return this.image;
  178. }
  179. public String getStr() {
  180. return str;
  181. }
  182. public void setStr(String str) {
  183. this.str = str;
  184. }
  185. public void setImage(ByteArrayInputStream image) {
  186. this.image = image;
  187. }
  188. }

struts2中获得验证码:

Java代码  
  1. /**
  2. * 功能:打开login.jsp的时候获得随机的验证码图片
  3. *
  4. * @return
  5. */
  6. public String getRandomPictrue() {
  7. VerificationCodeUtil vcu = VerificationCodeUtil.Instance();
  8. this.setInputStream(vcu.getImage());
  9. ActionContext.getContext().getSession().put("random", vcu.getVerificationCodeValue());// 取得随机字符串放入HttpSession
  10. return SUCCESS;
  11. }

另外前台jsp页面

Java代码  
  1. <script type="text/javascript">
  2. function changeValidateCode(obj) {
  3. //获取当前的时间作为参数,无具体意义
  4. var timenow = new Date().getTime();
  5. //每次请求需要一个不同的参数,否则可能会返回同样的验证码
  6. //这和浏览器的缓存机制有关系,也可以把页面设置为不缓存,这样就不用这个参数了。
  7. obj.src="getRandomPictrue?d="+timenow;
  8. }
  9. </script>
  10. <tr>
  11. <td height="24" valign="bottom"><div align="right"><span class="STYLE3">验证码</span></div></td>
  12. <td width="10" valign="bottom">&nbsp;</td>
  13. <td width="52" height="24" valign="bottom"><input type="text"  maxlength=4 name="yzm" id="textfield3" style="width:50px; height:17px; background-color:#87adbf; border:solid 1px #153966; font-size:12px; color:#283439; "></td>
  14. <td width="92" valign="bottom"><div align="center"><img src="getRandomPictrue.action" width="80" height="20" οnclick="changeValidateCode(this)"></div></td>
  15. </tr>

另外,在登录的时候,后台验证验证码是否输入正确

Java代码  
  1. public String userLogin() {
  2. String yanzhengma = this.getYzm().toLowerCase();//将验证码字符串全部转换成小写
  3. String random = getSessionAttribute("random").toString().toLowerCase();
  4. if(!yanzhengma.equals(random)){
  5. this.setRequestAttribute("errorMessage", "验证码错误,请核实后重新输入");
  6. return INPUT;
  7. }
  8. else{
  9. UserModel user = getUserService().loginJudge(getUserName(),
  10. getUserPass());
  11. if (user != null) {
  12. getSession().setAttribute("user", user);
  13. getSession().setAttribute("userId", user.getUserId());
  14. List<PermissionModel> treeList = userService.getTree(user
  15. .getUserId());
  16. getRequest().setAttribute("treeList", treeList);
  17. this.setRequestAttribute("username", user.getUserName());
  18. user.setLastLoginTime(DateUtil.getCurrentTimestamp());
  19. if (userService.addUser(user)) {
  20. logger.info(getUserName() + "登录成功");
  21. return SUCCESS;
  22. } else {
  23. logger.info(getUserName() + "登录失败,失败原因,更新lastLoginTime失败");
  24. this.setRequestAttribute("errorMessage", "服务器hold不住啦,请稍后重新登录");
  25. return INPUT;
  26. }
  27. } else {
  28. logger.info(getUserName() + "登录失败,用户名或者密码不正确");
  29. this.setRequestAttribute("errorMessage", "登录失败,用户名或者密码不正确");
  30. return INPUT;
  31. }
  32. }
  33. }
 
分享到:

package com.base.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

/**
 * 验证码类,主要生成几种不同类型的验证码
 * 第一种:简单验证码,4位随机数字
 * 第二种:英文字符加数字的验证码
 * 第三种:像铁路订票系统一样的验证码,肆+?=21
 *
 * @author 李朋飞
 *
 */
public class VerificationCodeUtil {
    private ByteArrayInputStream image;// 图像
    private String str;// 验证码
    private static final int WIDTH = 80;
    private static final int HEIGHT = 20;

public static void main(String[] arg) {
        VerificationCodeUtil vcu = VerificationCodeUtil.Instance();
        System.err.println(vcu.getVerificationCodeValue());
    }

/**
     * 功能:获取一个验证码类的实例
     *
     * @return
     */
    public static VerificationCodeUtil Instance() {
        return new VerificationCodeUtil();
    }

private VerificationCodeUtil() {
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
                BufferedImage.TYPE_INT_RGB);
        int randomNum = new Random().nextInt(3);
        if (randomNum == 0) {
            initNumVerificationCode(image);
        } else if (randomNum == 1) {
            initLetterAndNumVerificationCode(image);
        } else {
            initChinesePlusNumVerificationCode(image);
        }
    }

/**
     * 功能:设置第一种验证码的属性
     */
    public void initNumVerificationCode(BufferedImage image) {

Random random = new Random(); // 生成随机类
        Graphics g = initImage(image, random);
        String sRand = "";
        for (int i = 0; i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            // 将认证码显示到图象中
            g.setColor(new Color(20 + random.nextInt(110), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成
            g.drawString(rand, 13 * i + 6, 16);
        }
        this.setStr(sRand);/* 赋值验证码 */
        // 图象生效
        g.dispose();
        this.setImage(drawImage(image));
    }

/**
     * 功能:设置第二种验证码属性
     */
    public void initLetterAndNumVerificationCode(BufferedImage image) {

Random random = new Random(); // 生成随机类
        Graphics g = initImage(image, random);
        String[] letter = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
                "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
                "W", "X", "Y", "Z" };
        String sRand = "";
        for (int i = 0; i < 4; i++) {
            String tempRand = "";
            if (random.nextBoolean()) {
                tempRand = String.valueOf(random.nextInt(10));
            } else {
                tempRand = letter[random.nextInt(25)];
                if (random.nextBoolean()) {// 随机将该字母变成小写
                    tempRand = tempRand.toLowerCase();
                }
            }
            sRand += tempRand;
            g.setColor(new Color(20 + random.nextInt(10), 20 + random
                    .nextInt(110), 20 + random.nextInt(110)));
            g.drawString(tempRand, 13 * i + 6, 16);
        }
        this.setStr(sRand);/* 赋值验证码 */
        g.dispose(); // 图象生效
        this.setImage(drawImage(image));
    }

/**
     * 功能:设置第三种验证码属性 即:肆+?=24
     */
    public void initChinesePlusNumVerificationCode(BufferedImage image) {
        String[] cn = { "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾" };
        Random random = new Random(); // 生成随机类
        Graphics g = initImage(image, random);
        int x = random.nextInt(10) + 1;
        int y = random.nextInt(30);
        this.setStr(String.valueOf(y));
        g.setFont(new Font("楷体", Font.PLAIN, 14));// 设定字体
        g.setColor(new Color(20 + random.nextInt(10), 20 + random.nextInt(110),
                20 + random.nextInt(110)));
        g.drawString(cn[x - 1], 1 * 1 + 6, 16);
        g.drawString("+", 22, 16);
        g.drawString("?", 35, 16);
        g.drawString("=", 48, 16);
        g.drawString(String.valueOf(x + y), 61, 16);
        g.dispose(); // 图象生效
        this.setImage(drawImage(image));

}

public Graphics initImage(BufferedImage image, Random random) {
        Graphics g = image.getGraphics(); // 获取图形上下文
        g.setColor(getRandColor(200, 250));// 设定背景色
        g.fillRect(0, 0, WIDTH, HEIGHT);
        g.setFont(new Font("Times New Roman", Font.PLAIN, 14));// 设定字体
        g.setColor(getRandColor(160, 200)); // 随机产生165条干扰线,使图象中的认证码不易被其它程序探测到
        for (int i = 0; i < 165; 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);
        }
        return g;
    }

public ByteArrayInputStream drawImage(BufferedImage image) {
        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            ImageOutputStream imageOut = ImageIO
                    .createImageOutputStream(output);
            ImageIO.write(image, "JPEG", imageOut);
            imageOut.close();
            input = new ByteArrayInputStream(output.toByteArray());
        } catch (Exception e) {
            System.out.println("验证码图片产生出现错误:" + e.toString());
        }
        return input;
    }

/*
     * 功能:给定范围获得随机颜色
     */
    private 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);
    }

/**
     * 功能:获取验证码的字符串值
     *
     * @return
     */
    public String getVerificationCodeValue() {
        return this.getStr();
    }

/**
     * 功能:取得验证码图片
     *
     * @return
     */
    public ByteArrayInputStream getImage() {
        return this.image;
    }

public String getStr() {
        return str;
    }

public void setStr(String str) {
        this.str = str;
    }

public void setImage(ByteArrayInputStream image) {
        this.image = image;
    }
}

转载于:https://www.cnblogs.com/lanxuezaipiao/archive/2012/07/09/2583636.html

基于struts2+hibernate+spring(ssh2)的登录验证码的实现相关推荐

  1. 【struts2+hibernate+spring项目实战】实现用户登录功能(ssh)

    一.概述 从今天才开始有时间来总结总结以前自己练习的一些东西,希望总结出来对以后可以更加便捷的来学习,也希望可以帮助到正需要这些东西的同行人,一起学习,共同进步. 二. 登录功能总结 2.1.登录功能 ...

  2. Struts2 + Hibernate + Spring 以及javaweb模块问题解决(1)

    Struts2 + Hibernate + Spring 以及javaweb模块问题解决 1.资源文件的配置:src文件夹里面要配置,action所在的目录中也要配置. 2.<s: action ...

  3. 关于如何利用Struts2,Hibernate,Spring开发电子商业汇票系统

    关于如何利用Struts2,Hibernate,Spring开发电子商业汇票系统. 首先先说说电子商业汇票的种类: 1.电子银行承兑汇票 2.电子商业承兑汇票 另外电子商业汇票与纸票的区别: 电子商业 ...

  4. Struts2+Hibernate+Spring 整合示例

    转自:https://blog.csdn.net/tkd03072010/article/details/7468769 Struts2+Hibernate+Spring 整合示例 Spring整合S ...

  5. struts2+hibernate+spring配置详解

    #struts2+hibernate+spring配置详解 struts2+hibernate+spring配置详解 哎 ,当初一个人做好难,现在终于弄好了,希望自学这个的能少走些弯路. 以下是自己配 ...

  6. 基于struts2、spring、spring data jpa实现poi导入 + pinyin4j将汉字转换为拼音

    基于struts2.spring.spring data jpa实现poi导入 + pinyin4j将汉字转换为拼音 1.引入坐标到pom.xml <!-- Excel解析工具类 -->& ...

  7. 【struts2+hibernate+spring项目实战】Spring计时器任务 Spring整合JavaMail(邮件发送)(ssh)

    一.常用数据频度维护 对于系统使用度较高的数据,客户在查看时希望这些数据最好先出现,此时需要为其添加排序规则.在进行排序时,使用次数成为排序的依据.因此需要设置一个字段用来描述某种数据的使用次数,也就 ...

  8. 【struts2+hibernate+spring项目实战】java监听器实现权限控制系统和资源获取优化(ssh)

    一.权限控制系统 权限控制系统即用户登录后,如果操作了不能访问的操作,系统将其拦截. 权限控制系统设计需求: 系统功能并不是所有功能都需要被控制,例如登录功能无需校验 设计方案:资源中没有出现的功能将 ...

  9. SSH(Struts2+Hibernate+Spring)开发策略

    很多小伙伴可能一听到框架两个字就会马上摇头,脑子里立刻闪现一个词---"拒绝",其实我也不例外,但我想告诉大家的是,当你真正掌握它时,你会发现**SSH**用起来是那么顺手,因为它 ...

最新文章

  1. 转贴一篇很不错的有关ASP.NET Session的分析文章
  2. 学习笔记-安装ELK5
  3. 一只快乐的野指针_野酸枣
  4. 用fft对信号进行频谱分析实验报告_示波器上的频域分析利器,Spectrum View测试分析...
  5. linux C++ 多进程初步02
  6. 逻辑回归算法python_逻辑回归算法原理和例子
  7. 我搭的神经网络不work该怎么办!看看这11条新手最容易犯的错误
  8. User-Item协同自回归模型的协同过滤
  9. java jboss_jboss配置方法简明教程
  10. html5在线画板菱形怎么画,使用HTML5构建一个在线画板应用
  11. 水花兄弟又凑齐了(20220111 Week2-1)
  12. Ubuntu发烧友三部曲 进阶篇
  13. springboot定期清理文件
  14. 小米文件管理连接服务器,小米文件管理器中的远程管理无法连接解决方法
  15. 『关于摄影的前后期』
  16. NOI / 1.7编程基础之字符串题目排名状态提问15:整理药名
  17. ui设计教程分享:关于Logo设计要素
  18. 区块链技术与其在旅游行业的应用
  19. ZUCC_Object Oriented Programming_Lab06 Objects and Classes
  20. 时序知识图谱的增量构建

热门文章

  1. svpwm仿真_三相三线逆变_并网仿真建模
  2. C语言函数参数压栈顺序为何是从右到左?
  3. 《Linux内核设计与实现》读书笔记(十五)- 进程地址空间(kernel 2.6.32.60)
  4. tensorflow 之 ValuError: At least two variables have the same name: bottom/bn1/beta_power0 等
  5. windows和linux下的文件路径表示
  6. python列表常用方法_python之 列表常用方法
  7. Andorid App内部跟随熊语言改变
  8. java实现 SSL双向认证
  9. 查看Oracle数据库表空间大小(空闲、已使用),是否要增加表空间的数据文件
  10. ASP.NET MVC3 部署的前期工作