查看: 6896|回复: 6

[精华] Web验证码的开发实战

[复制链接]
论坛徽章:
63
2010广州亚运会纪念徽章:台球
日期:2010-10-18 12:43:48茶鸡蛋
日期:2013-01-09 10:59:002013年新春福章
日期:2013-02-25 14:51:24奥运会纪念徽章:帆船
日期:2013-04-02 17:07:052013年新春福章
日期:2013-04-08 17:42:48奥运纪念徽章
日期:2013-07-18 13:55:12优秀写手
日期:2013-12-18 09:29:10马上有车
日期:2014-03-20 16:13:24马上有房
日期:2014-03-20 16:14:11马上有钱
日期:2014-03-20 16:14:11
发表于 2012-6-2 22:18 | 显示全部楼层 |阅读模式
本帖最后由 chszs 于 2012-6-2 22:27 编辑

Web验证码的开发实战
2012-6-2
版权声明:本文属于原创,版权归作者chszs所有,使用源码无任何限制,但转载文章需经作者同意。

一、简介
当前的Web开发,少不了验证码功能。验证码最主要的功能,就是防止机器人注册,保证注册的用户都是真实用户。
目前,验证码功能使用已经比较普遍,网上也能搜索到不少相关的例子。本文属于原创,是我自己琢磨验证码的实现,最终用JSP实现了验证码功能。当然,本文的例子也可移植到.NET环境,保持算法思想即可。
二、准备工作
本文在Windows环境下开发,使用的工具有:
1JDK 6
我使用的是jdk-6u31-windows-i586.exe,相近的版本都没问题。
2Eclipse
我使用的是eclipse-jee-indigo-SR2-win32.zip。要说明一点,Eclipse是开源、免费的Java开发IDE,因此应该尽可能使用其最新的版本,充分发挥其最新的特性,提高开发效率。
3Tomcat
我使用的是apache-tomcat-7.0.27.zip,其Windows安装版MSI版也可以,ZIP版本直接解压使用,更加方便。
以上三个工具的安装过程省略,如遇到问题,网上有大量的资料供参阅。
三、验证码开发
1、创建动态Web项目
项目名为webt2,注意下面的三项设置:
(1) Target runtime:设置为Apache Tomcat v7.0
(2) Dynamic web module version:设置为3.0
(3) Configuration:设置为Default Configuration for Apache Tomcat v7.0
图片1.png
另外要注意一点,Servlet 3.0项目,可以不需要web.xml配置文件。
图片2.png
2、创建包
我命名为ch.learn
3、创建类
创建产生随即字符的工具类,我命名为RandomUtil.java,内容如下:
  1. package ch.learn;
  2. import java.awt.*;
  3. import java.util.*;

  4. public class RandomUtil {
  5. private char getRandomAlphabet(){
  6. String word = "abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  7. Double n = Math.random()*word.length();
  8. return word.charAt(n.intValue());
  9. }
  10. private char getRandomLowerAlphabet(){
  11. String word = "abcdefghijklmopqrstuvwxyz";
  12. Double n = Math.random()*word.length();
  13. return word.charAt(n.intValue());
  14. }
  15. private char getRandomUpperAlphabet(){
  16. String word = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  17. Double n = Math.random()*word.length();
  18. return word.charAt(n.intValue());
  19. }
  20. private String getRandomNumber(){
  21. Random random = new Random();
  22. return String.valueOf(random.nextInt(10));
  23. }
  24. private char getRandomAlphabetAndNumber(){
  25. String word = "abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  26. Double n = Math.random()*word.length();
  27. return word.charAt(n.intValue());
  28. }
  29. public Color getRandomColor(int fc, int bc){
  30. Random random = new Random();
  31. if(fc>255) fc = 255;
  32. if(bc>255) bc = 255;
  33. int r = fc + random.nextInt(bc - fc);
  34. int g = fc + random.nextInt(bc - fc);
  35. int b = fc + random.nextInt(bc - fc);
  36. return new Color(r, g, b);
  37. }
  38. /**
  39. * 生成随机字符
  40. * @param len 字符的长度
  41. * @param point 指示器: 0表示生成小写字母, 1表示生成大写字母, 2表示生成大小写字母,
  42. * 3表示生成数字, 4表示生成大小写字母和数字
  43. * @return 生成的字符串
  44. */
  45. public String getRandomWord(int len, int point){
  46. if(len<=0)
  47. return null;
  48. StringBuffer str = new StringBuffer();
  49. for(int i=0; i<len; i++){
  50. if(point == 0)
  51. str.append(getRandomLowerAlphabet());
  52. else if(point == 1)
  53. str.append(getRandomUpperAlphabet());
  54. else if(point == 2)
  55. str.append(getRandomAlphabet());
  56. else if(point == 3)
  57. str.append(getRandomNumber());
  58. else if(point == 4)
  59. str.append(getRandomAlphabetAndNumber());
  60. else
  61. return null;
  62. }
  63. return str.toString();
  64. }
  65. public static void main(String[] args){
  66. RandomUtil util = new RandomUtil();
  67. System.out.println(util.getRandomWord(4, 4));
  68. }
  69. }
复制代码

4、创建JSP文件
WebContent目录下创建JSP文件,我命名为checknum.jsp,内容如下:
  1. <%@ page language="java" contentType="image/jpg" errorPage="" %>
  2. <%@ page import="java.awt.*, java.awt.image.*, java.util.*, javax.imageio.*" %>
  3. <%@ page import="ch.learn.RandomUtil" %>
  4. <%!
  5. RandomUtil util = new RandomUtil();
  6. %>

  7. <%
  8. response.setHeader("Pragma", "No-cache");
  9. response.setHeader("Cache-Control", "No-cache");
  10. response.setDateHeader("Expires", 0);
  11. int width=60, height=20;
  12. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  13. Graphics g = image.getGraphics();
  14. Random random = new Random();
  15. g.setColor(util.getRandomColor(201, 255));
  16. g.fillRect(0, 0, width, height);
  17. g.setFont(new Font("Times New Roman", Font.BOLD, 18));
  18. g.setColor(util.getRandomColor(160, 200));
  19. for(int i=0; i<155; i++){
  20. int x = random.nextInt(width);
  21. int y = random.nextInt(height);
  22. int x1 = random.nextInt(12);
  23. int y1 = random.nextInt(12);
  24. g.drawLine(x, y, x+x1, y+y1);
  25. }
  26. int len = 4;
  27. String word = util.getRandomWord(len, 4);
  28. g.setColor(new Color(20+random.nextInt(110), 20+random.nextInt(110), 20+random.nextInt(110)));
  29. g.drawString(word, 8, 16);

  30. session.setAttribute("rand", word);
  31. g.dispose();
  32. ImageIO.write(image, "JPG", response.getOutputStream());
  33. out.clear();
  34. out = pageContext.pushBody();
  35. %>
复制代码

5、创建登录测试页面
为了测试验证码功能能否正常工作,这里以最简化的方式写了一个测试网页,我取名为test.htm,内容如下:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>验证码测试</title>
  6. </head>
  7. <body>
  8. <img src="checknum.jsp" id="code" width="60" height="20" />
  9. </body>
  10. </html>
复制代码


四、测试
到此,项目已经开发完毕。
1、项目结构
整个项目的结构如下图所示:
图片3.png
说明一点,ShowParameters.javaTestAnnotationServlet.java、包coreservlets与本验证码功能无关,对本测试无任何影响。
2、部署并运行
鼠标右键点击项目根节点webt2,选择Run As-->Run on Server
webt2程序在Tomcat 7内启动,在浏览器输入地址:http://localhost:8080/webt2/test.htm
浏览器显示如下结果:
图片4.png
按下F5刷新页面,验证码会不断变换。
图片5.png
可见,验证码功能运行正常。
五、总结
实现此功能的开发并不复杂,大家可根据自己的需要自行修改源码。另外,再说明一点,RandomUtil.javagetRandomWord提供了几种选择,可以只生成小写字母的验证码,可以只生成大写字母的验证码,可以只生成大小写字母的验证码,可以只生成数字的验证码,可以只生成大小写字母和数字的验证码。

认证徽章
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
发表于 2012-6-5 05:17 | 显示全部楼层
挺好的。

使用道具 举报

回复
认证徽章
论坛徽章:
104
生肖徽章2007版:猪
日期:2012-07-12 14:24:56菠菜神灯
日期:2013-05-26 22:03:18生肖徽章2007版:猪
日期:2012-07-19 11:10:12生肖徽章2007版:猪
日期:2012-07-19 11:10:12生肖徽章2007版:猪
日期:2012-07-11 19:07:11生肖徽章2007版:猪
日期:2012-07-19 11:10:12生肖徽章2007版:猪
日期:2012-07-19 11:10:12ITPUB伯乐
日期:2012-05-22 15:05:25NBA季后赛纪念徽章
日期:2013-06-21 14:52:05NBA季后赛大富翁
日期:2013-06-21 14:57:11
发表于 2012-6-5 08:35 | 显示全部楼层
不错!顶!

使用道具 举报

回复
论坛徽章:
4
生肖徽章2007版:牛
日期:2008-01-02 17:35:53奥运会纪念徽章:马术
日期:2008-10-24 13:03:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:072013年新春福章
日期:2013-02-25 14:51:24
发表于 2012-6-5 17:11 | 显示全部楼层
very good

使用道具 举报

回复
求职 : 数据库管理员
论坛徽章:
10
ITPUB十周年纪念徽章
日期:2011-11-01 16:25:22茶鸡蛋
日期:2013-06-05 12:50:512013年新春福章
日期:2013-05-27 10:23:002013年新春福章
日期:2013-05-27 10:23:002013年新春福章
日期:2013-05-27 10:23:002013年新春福章
日期:2013-02-25 14:51:24茶鸡蛋
日期:2013-02-22 15:45:00ITPUB 11周年纪念徽章
日期:2012-10-09 18:11:482012新春纪念徽章
日期:2012-01-04 11:55:05ITPUB社区千里马徽章
日期:2013-06-09 10:15:34
发表于 2012-6-7 09:42 | 显示全部楼层
不错,java都网的差不多了。

使用道具 举报

回复
论坛徽章:
0
发表于 2012-6-7 19:17 | 显示全部楼层
String类型不是有大小写转换的方法吗?.toUpperCase();toLowerCase();
而且,直接在ASCII码的英文数字区间中随机取就可以了,要大写或者小写转换一下就可以了.

使用道具 举报

回复
论坛徽章:
0
发表于 2013-7-17 17:45 | 显示全部楼层
不错不错

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表