验证码基础

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

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

二.图文验证码的原理

:在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()"> 看不清,换一个</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.工程项目结构,及运行截图

JAVAWEB项目如何实现验证码的更多相关文章

  1. JAVAWEB项目如何实现验证码 (转)

    JAVAWEB项目如何实现验证码 2012-12-21 21:19 56026人阅读 评论(36) 收藏 举报 .embody { padding: 10px 10px 10px; margin: 0 ...

  2. JavaWeb项目实现图片验证码

    一.什么是图片验证码? 可以参考下面这张图: 我们在一些网站注册的时候,经常需要填写以上图片的信息. 这种图片验证方式是我们最常见的形式,它可以有效的防范恶意攻击者采用恶意工具,调用“动态验证码短信获 ...

  3. 手把手教你做JavaWeb项目:登录模块

    现如今,无论是客户端还是移动端,无论是游戏登陆还是社交平台登陆,无处不在的“登陆”.那么你知道怎么制作吗?今天就为你娓娓道来: 用户登录 在各大信息管理系统中,登录功能是必不可少的,他的作用就是验证用 ...

  4. log4j在javaWeb项目中的使用

    在前边的文章中对log4j的配置文件进行了说明,今天介绍如何在普通的javaWeb项目中使用log4j. 在日常的开发过程中,日志使用的很频繁,我们可以利用日志来跟踪程序的错误,程序运行时的输出参数等 ...

  5. Druid使用起步—在javaWeb项目中配置监控 连接池

    当我们在javaWEB项目中使用到druid来作为我们的连接池的时候,一定不会忘了添加监控功能.下面我们就来看一下,在一个简单的web项目中(尚未使用任何框架)我们是如果来配置我们的web.xml来完 ...

  6. (转)一个JavaWeb项目开发总结

    原文地址:http://www.cnblogs.com/lzb1096101803/p/4907775.html 一.学会如何读一个JavaWeb项目源代码 步骤:表结构->web.xml-&g ...

  7. JavaWeb项目前端规范(采用命名空间使js深度解耦合)

    没有规矩不成方圆,一个优秀的代码架构不仅易于开发和维护,而且是一门管理与执行的艺术. 这几年来经历了很多项目,对代码之间的强耦合及书写不规范,维护性差等问题深恶痛绝.在这里,通过仔细分析后,结合自己的 ...

  8. 关于服务器响应,浏览器请求的理解以及javaWeb项目的编码问题

    1.服务器(Server)响应,浏览器(Brower)请求: 对于B/S的软件,数据的传递体现在,用户利用浏览器请求,以获得服务器响应.在JavaWeb项目中,大致包含.java文件的数据处理模块,和 ...

  9. 四、使用Maven和使用Eclipse构建javaWeb项目

    环境前边已经搭建过了,我们就再弄了. 1.使用Maven构建javaWeb项目 (1).键入以下命令: $ mvn archetype:generate -DgroupId=com.holytax.w ...

随机推荐

  1. Mybatis 使用maven插件mybatis-generator自动生成entities和SQL和mapper

    第一步:在pom中添加该插件的配置,我直接把pom贴上来好了 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns ...

  2. UVA 11464 暴力+位运算 ***

    题意:给你一个 n * n 的 01 矩阵,现在你的任务是将这个矩阵中尽量少的 0 转化为 1 ,使得每个数的上下左右四个相邻的数加起来是偶数.求最少的转化个数. 新风格代码 lrj书上说的很清楚了, ...

  3. 使用ajax.dll时js脚本错误-XXX未定义

    操作系统:Windows 7 IIS:7.5 ajax.dll现在用的比较少,但是以前的项目有这个,使用的时候很容易出现这个错误,因为总是会遗漏配置. 使用ajax.dll时,js脚本错误,无法调用后 ...

  4. Borland C++建立工程菜鸟教程

    实在不敢相信,学校里现在教学用的编译器还是七八十年代的老古董,难道这东西更能培养从没接触过代码的学生深刻理解c语言的运行流程,不得不说像VisualStdio这样的重量级开发环境确实屏蔽了很多底层的运 ...

  5. Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并

    D. Developing Game   Pavel is going to make a game of his dream. However, he knows that he can't mak ...

  6. 如何快速地从mongo中提取数据到numpy以及pandas中去

    mongo数据通常过于庞大,很难一下子放进内存里进行分析,如果直接在python里使用字典来存贮每一个文档,使用list来存储数据的话,将很快是内存沾满.型号拥有numpy和pandas import ...

  7. 如何在本地搭建IIS服务器

    http://jingyan.baidu.com/article/8ebacdf021313d49f65cd525.html

  8. dubbo分析总结

    dubbo是服务化框架的优秀代表,架构设计很是优异,主要体现在框架本身的设计和实现 ,设计层面更多的是架构设计优秀,实现层面更多的是. dubbo源码分析好文章 http://herman-liu76 ...

  9. event

    当一个事件被调用后,它会收到一个参数,第一个参数就是事件对象,事件对象包含type, target, timestamp三个. 类型:事件的名称,例如:点击目标:事件的目标元素时间戳:事件触发的时间

  10. HTML当中特殊字符的表示

    (回车换行) <br> (空格符)   &(AND符号) & <(左尖括号.小于号) < >(右尖括号.大于号) > °(度) ° •(间隔符) • ...