一.什么是验证码及它的作用

验 证码为全自动区分计算机和人类的图灵测试的缩写,是一种区分用户是计算机的公共全自动程序,这个问题可以由计算机生成并评判,但是必须只有人类才能解答. 可以防止恶意破解密码、刷票、论坛灌水、有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录。

二.图文验证码的原理

在 servlet中随机生成一个指定位置的验证码,一般为四位,然后把该验证码保存到session中.在通过Java的绘图类以图片的形式输出该验证码。 为了增加验证码的安全级别,可以输出图片的同时输出干扰线,最后在用户提交数据的时候,在服务器端将用户提交的验证码和Session保存的验证码进行比 较。

三.验证码所需的技术

i.因为验证码中的文字,数字,应为都是可变的,故要用到随机生成数技术。

ii.如果验证码中包含汉字,则要用到汉字生成技术.

iii.可以使用Ajax技术实现局部刷新

iv.可以使用图片的缩放和旋转技术,

vi.随机绘制干扰线(可以是折现,直线等)

vii.如果考虑到验证码的安全性,可以使用MD5加密.

验证码模块实例

1.编写生成英文,数字,汉字随机生成的Servlet类.源代码如下:

  1. package com.servlet;
  2. import java.awt.*;
  3. import java.awt.geom.*;
  4. import java.awt.image.*;
  5. import java.io.*;
  6. import java.util.*;
  7. import javax.servlet.ServletException;
  8. import javax.servlet.http.HttpServlet;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import javax.servlet.http.HttpSession;
  12. import javax.imageio.ImageIO;
  13. public class PictureCheckCode extends HttpServlet {
  14. private static final long serialVersionUID = 1L;
  15. public PictureCheckCode() {
  16. super();
  17. }
  18. public void destroy() {
  19. super.destroy();
  20. }
  21. public void init() throws ServletException {
  22. super.init();
  23. }
  24. /*该方法主要作用是获得随机生成的颜色*/
  25. public Color getRandColor(int s,int e){
  26. Random random=new Random ();
  27. if(s>255) s=255;
  28. if(e>255) e=255;
  29. int r,g,b;
  30. r=s+random.nextInt(e-s);    //随机生成RGB颜色中的r值
  31. g=s+random.nextInt(e-s);    //随机生成RGB颜色中的g值
  32. b=s+random.nextInt(e-s);    //随机生成RGB颜色中的b值
  33. return new Color(r,g,b);
  34. }
  35. @Override
  36. public void service(HttpServletRequest request, HttpServletResponse response)
  37. throws ServletException, IOException {
  38. //设置不缓存图片
  39. response.setHeader("Pragma", "No-cache");
  40. response.setHeader("Cache-Control", "No-cache");
  41. response.setDateHeader("Expires", 0);
  42. //指定生成的响应图片,一定不能缺少这句话,否则错误.
  43. response.setContentType("image/jpeg");
  44. int width=86,height=22;     //指定生成验证码的宽度和高度
  45. BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //创建BufferedImage对象,其作用相当于一图片
  46. Graphics g=image.getGraphics();     //创建Graphics对象,其作用相当于画笔
  47. Graphics2D g2d=(Graphics2D)g;       //创建Grapchics2D对象
  48. Random random=new Random();
  49. Font mfont=new Font("楷体",Font.BOLD,16); //定义字体样式
  50. g.setColor(getRandColor(200,250));
  51. g.fillRect(0, 0, width, height);    //绘制背景
  52. g.setFont(mfont);                   //设置字体
  53. g.setColor(getRandColor(180,200));
  54. //绘制100条颜色和位置全部为随机产生的线条,该线条为2f
  55. for(int i=0;i<100;i++){
  56. int x=random.nextInt(width-1);
  57. int y=random.nextInt(height-1);
  58. int x1=random.nextInt(6)+1;
  59. int y1=random.nextInt(12)+1;
  60. BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL); //定制线条样式
  61. Line2D line=new Line2D.Double(x,y,x+x1,y+y1);
  62. g2d.setStroke(bs);
  63. g2d.draw(line);     //绘制直线
  64. }
  65. //输出由英文,数字,和中文随机组成的验证文字,具体的组合方式根据生成随机数确定。
  66. String sRand="";
  67. String ctmp="";
  68. int itmp=0;
  69. //制定输出的验证码为四位
  70. for(int i=0;i<4;i++){
  71. switch(random.nextInt(3)){
  72. case 1:     //生成A-Z的字母
  73. itmp=random.nextInt(26)+65;
  74. ctmp=String.valueOf((char)itmp);
  75. break;
  76. case 2:     //生成汉字
  77. String[] rBase={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
  78. //生成第一位区码
  79. int r1=random.nextInt(3)+11;
  80. String str_r1=rBase[r1];
  81. //生成第二位区码
  82. int r2;
  83. if(r1==13){
  84. r2=random.nextInt(7);
  85. }else{
  86. r2=random.nextInt(16);
  87. }
  88. String str_r2=rBase[r2];
  89. //生成第一位位码
  90. int r3=random.nextInt(6)+10;
  91. String str_r3=rBase[r3];
  92. //生成第二位位码
  93. int r4;
  94. if(r3==10){
  95. r4=random.nextInt(15)+1;
  96. }else if(r3==15){
  97. r4=random.nextInt(15);
  98. }else{
  99. r4=random.nextInt(16);
  100. }
  101. String str_r4=rBase[r4];
  102. //将生成的机内码转换为汉字
  103. byte[] bytes=new byte[2];
  104. //将生成的区码保存到字节数组的第一个元素中
  105. String str_12=str_r1+str_r2;
  106. int tempLow=Integer.parseInt(str_12, 16);
  107. bytes[0]=(byte) tempLow;
  108. //将生成的位码保存到字节数组的第二个元素中
  109. String str_34=str_r3+str_r4;
  110. int tempHigh=Integer.parseInt(str_34, 16);
  111. bytes[1]=(byte)tempHigh;
  112. ctmp=new String(bytes);
  113. break;
  114. default:
  115. itmp=random.nextInt(10)+48;
  116. ctmp=String.valueOf((char)itmp);
  117. break;
  118. }
  119. sRand+=ctmp;
  120. Color color=new Color(20+random.nextInt(110),20+random.nextInt(110),random.nextInt(110));
  121. g.setColor(color);
  122. //将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示
  123. /*将文字旋转制定角度*/
  124. Graphics2D g2d_word=(Graphics2D)g;
  125. AffineTransform trans=new AffineTransform();
  126. trans.rotate((45)*3.14/180,15*i+8,7);
  127. /*缩放文字*/
  128. float scaleSize=random.nextFloat()+0.8f;
  129. if(scaleSize>1f) scaleSize=1f;
  130. trans.scale(scaleSize, scaleSize);
  131. g2d_word.setTransform(trans);
  132. g.drawString(ctmp, 15*i+18, 14);
  133. }
  134. HttpSession session=request.getSession(true);
  135. session.setAttribute("randCheckCode", sRand);
  136. g.dispose();    //释放g所占用的系统资源
  137. ImageIO.write(image,"JPEG",response.getOutputStream()); //输出图片
  138. }
  139. }

2.配置Servlet

在web.xml中的配置如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="2.5"
  3. xmlns="http://java.sun.com/xml/ns/javaee"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  6. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  7. <servlet>
  8. <description>输出验证码</description>
  9. <display-name>This is the display name of my J2EE component</display-name>
  10. <servlet-name>PictureCheckCode</servlet-name>
  11. <servlet-class><span style="color: #ff0000;">com.servlet.PictureCheckCode</span></servlet-class>
  12. </servlet>
  13. <servlet-mapping>
  14. <servlet-name>PictureCheckCode</servlet-name>
  15. <url-pattern>/<span style="color: #ff0000;">PictureCheckCode</span></url-pattern>
  16. </servlet-mapping>
  17. <welcome-file-list>
  18. <welcome-file>index.jsp</welcome-file>
  19. </welcome-file-list>
  20. </web-app>

3.测试验证码

可以编写JSP页面来验证是否可以输出验证码图片,JSP代码如下:

1.index.jsp:显示界面

  1. <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  3. <html>
  4. <head>
  5. <title>验证码</title>
  6. <script language="javascript">
  7. function myReload() {
  8. document.getElementById("CreateCheckCode").src = document
  9. .getElementById("CreateCheckCode").src
  10. + "?nocache=" + new Date().getTime();
  11. }
  12. </script>
  13. </head>
  14. <body>
  15. <form action="Check.jsp" method="post">
  16. <input name="checkCode" type="text" id="checkCode" title="验证码区分大小写"
  17. size="8" ,maxlength="4" />
  18. <img src="PictureCheckCode" id="CreateCheckCode" align="middle">
  19. <a href="" onclick="myReload()">&nbsp;看不清,换一个</a>
  20. <input type="submit" value="提交" />
  21. </form>
  22. </body>
  23. </html>

2.Check.jsp :主要验证提交的数据是否和Session中保存的验证码是否相同

  1. <%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
  2. <html>
  3. <head>
  4. <title>验证码校验</title>
  5. </head>
  6. <body>
  7. <%
  8. String checkcode=request.getParameter("checkCode");
  9. if(checkcode.equals("")||checkcode==null){
  10. out.print("<script>alert('请输入验证码');window.location.href('index.jsp')</script>");
  11. }else{
  12. if(!checkcode.equalsIgnoreCase((String)session.getAttribute("randCheckCode"))){
  13. out.print("<script>alert('验证码不正确,请重新输入');history.back(-1);</script>");
  14. }else{
  15. out.print("登录成功");
  16. }
  17. }
  18. %>
  19. </body>
  20. </html>

4.工程项目结构,及运行截图

Java Web模块——验证码模块的更多相关文章

  1. java web 实现验证码

    验证码的作用:通常的登录或者注册系统时,都会要求用户输入验证码,以此区别用户行为和计算机程序行为,目的是有人防止恶意注册.暴力破解密码等. 实现验证码的思路:用 server 实现随机生成数字和字母组 ...

  2. java web中验证码生成的demo

    首先创建一个CaptailCode类 package com.xiaoqiang.code; import java.awt.*; import java.awt.font.FontRenderCon ...

  3. Java Web之验证码

    今天来模拟一下验证码,我们需要三个文件,两个Servlet,一个jsp 直接贴代码吧 RandomCodeServlet:主要负责生产验证码 package com.vae.RandomCode; i ...

  4. OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统

    OSGi 系列(一)之什么是 OSGi :Java 语言的动态模块系统 OSGi 的核心:模块化.动态.基于 OSGi 就可以模块化的开发 java 应用,模块化的部署 java 应用,还可以动态管理 ...

  5. OSGi是什么:Java语言的动态模块系统(一)

    OSGi是什么 OSGi亦称做Java语言的动态模块系统,它为模块化应用的开发定义了一个基础架构.OSGi容器已有多家开源实现,比如Knoflerfish.Equinox和Apache的Felix.您 ...

  6. python-Day5-深入正则表达式--冒泡排序-时间复杂度 --常用模块学习:自定义模块--random模块:随机验证码--time & datetime模块

    正则表达式   语法:             mport re #导入模块名 p = re.compile("^[0-9]") #生成要匹配的正则对象 , ^代表从开头匹配,[0 ...

  7. Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块

    Python第十三天   django 1.6   导入模板   定义数据模型   访问数据库   GET和POST方法    SimpleCMDB项目   urllib模块   urllib2模块 ...

  8. node(03)--利用 HTTP 模块 URl 模块 PATH 模块 FS 模块创建一个 WEB 服务器

    Web 服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等 Web 客户端提供文档,也可以放置网站文件,让全世界浏览:可以放置数据文件,让全世界下载.目前最主流的三个 We ...

  9. Java安全之ysoserial-JRMP模块分析(一)

    Java安全之ysoserial-JRMP模块分析(一) 首发安全客:Java安全之ysoserial-JRMP模块分析(一) 0x00 前言 在分析到Weblogic后面的一些绕过方式的时候,分析到 ...

随机推荐

  1. 第一天开通博客,就粗略写一下刚了解TCP/IP协议工作过程

    Tcp/Ip协议分为四层:底层到高层顺序 链路层(硬件,网卡这些) 网络层(选择一条传输路径,如何从一台计算机请求另一条计算机) 传输层(遵循TCP(传输控制协议),UDP(用户数距协议)这些协议) ...

  2. Scrum角色

    产品负责人(Product Owner)的职责如下: 确定产品的功能. 决定发布的日期和发布内容. 为产品的profitability       of the product (ROI)负责. 根据 ...

  3. Map/Reduce中Join查询实现

    张表,分别较data.txt和info.txt,字段之间以/t划分. data.txt内容如下: 201001    1003    abc 201002    1005    def 201003  ...

  4. VS2012打包部署Winform程序

    打包前的准备工作: 新建一个打包部署项目,点OK,如果是第一次使用的话,会打开一个网页,按照提示的步骤来做, 点击上面的step2的网址,进入到另一个网页: 填写完右边的信息,点击“download ...

  5. 无线网WEP的安全测试及防范

    650) this.width=650;" border="0" alt="" src="http://img1.51cto.com/att ...

  6. UVALive 3959 Rectangular Polygons (排序贪心)

    Rectangular Polygons 题目链接: http://acm.hust.edu.cn/vjudge/contest/129733#problem/G Description In thi ...

  7. CString的GetBuffer用法,GetBuffer本质,GetBuffer常见问题解决方法

    一.函数原型 CString::GetBuffer LPTSTR GetBuffer( int nMinBufLength ); throw( CMemoryException ); Return V ...

  8. halcon,C# 学习

    Halcon学习之一:查询图像参数 1.get_grayval ( Image : : Row, Column : Grayval ) 计算Image图像中坐标为(Row,Column)的点的灰度值G ...

  9. C#调用存储过程详解

    连接字符串: string conn = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].C ...

  10. javascript自执行函数为什么要把windows作为参数传进去

    http://segmentfault.com/q/1010000000311686 (function (window, $, undefined) { play=function(){ $(&qu ...