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

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

二.图文验证码的原理

在 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. The remote SSH server rejected X11 forwarding request

    两台相同的虚拟机,一台没有错误,一个经常出现警告,内容如下所示: The remote SSH server rejected X11 forwarding request 找了很多方法,最后发现是安 ...

  2. 黑马程序员——OC与C语言的异同比较

    1.  文件介绍:Objective-C 也使用头文件(header files),后缀为 .h, 但使用 .m(即 message, 其他面向对象编程语言也叫 method),作为源文件的后缀.   ...

  3. C++学习之路--类的构建以及数据转换存储

    注意理解下面的代码,数据的处理与转换. 头文件: #ifndef STACK_H #define STACK_H class Stack { struct Link { void* data; Lin ...

  4. JavaEE5 Tutorial_Jsp,EL

      Jsp的各种元素在转化为servlet时处理是不一样的:指令,控制web容器如何处理页面脚本,被插入到生成的servlet里EL表达式,作为参数传递到解析器get/set Property,变成方 ...

  5. DzzOffice1.0 Beta2 全新安装图文教程及界面简单了解

    本文说明:本文档用于帮助您全新安装完整的 DzzOffice Beta版软件.DzzOffice 是一款开源的云存储与应用管理工具,主要用于企业管理阿里云.亚马逊等云存储等空间,把空间可视化分配给成员 ...

  6. js 多物体运动

    <!doctype html> <html> <head> <meta charset = "utf-8"> <title&g ...

  7. 新 esb-cs-tool.jar 参数说明

    旧esb-cs-tool.jar 使用说明 : invoke(RequestBusinessObject requestBo) 旧参数说明: requestBo  : 封装好的请求参数大对象  Req ...

  8. 关于网上流传的四个原版Windows XP_SP2全面了解

    如何查看你的XP SP2是否原版?打开Windows/System32/找到EULA这个文本文档(即eula.txt):打开在最后一行:有一个EULAID:XPSP2_RM.0_PRO_RTL_CN ...

  9. 用PyInstaller把Python代码打包成单个独立的exe可执行文件

    之前就想要把自己的BlogsToWordpress打开成exe了.一直没去弄. 又看到有人提到python打开成exe的问题. 所以打算现在就去试试. 注:此处之所有选用BlogsToWordpres ...

  10. java_web用户的自动登录模块的实现

    javaBean的代码 package bean; import java.io.Serializable; public class Admin implements Serializable{ / ...