验证码基础

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

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

二.图文验证码的原理

:在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. MySQL 相关

    Innodb引擎 Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别.该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统. 但是该引擎不支持FULLT ...

  2. Asp.net+JS 分页

    function pagestart() {//初始化页面,获取公司新闻 $("#pagediv").hide(); $("); var pagesize = $(&qu ...

  3. LeetCode——Single Number II(找出数组中只出现一次的数2)

    问题: Given an array of integers, every element appears three times except for one. Find that single o ...

  4. js文件上传

    DOM: <form id="clueForm" class="insert-dialog" action="/xxx/xxx"met ...

  5. keyCode,charCode,which

    1.触发顺序keydown keypress keyup,但keypress事件只有输入相关按键才会触发,功能按键不会触发keypress事件(keypress事件有个额外的charCode属性) 2 ...

  6. JS 之Blob 对象类型

    原文 http://blog.csdn.net/oscar999/article/details/36373183 什么是Blob? Blob 是什么? 这里说的是一种Javascript的对象类型. ...

  7. jQuery Live Query 插件

    http://www.cnblogs.com/sunjing/archive/2008/12/06/1349097.html 上篇日志里写到的那个问题其实有种更简单的解决办法,就是使用jquery的L ...

  8. ACM: FZU 2102 Solve equation - 手速题

     FZU 2102   Solve equation Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & ...

  9. 洛谷 P2725 邮票 Stamps Label:DP

    题目背景 给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K —— 表示信封上能够贴 K 张邮票.计算从 1 到 M 的最大连续可贴出的邮资. 题目描述 例如,假设有 1 分和 3 ...

  10. Markdown工具的使用

    Markdown 工具的使用 基本操作 CMD-N 建立一个新的工作表 CMD-SHIFT-N 建立一个新的组 CMD-CTRL-N 建立一个新的过滤器 项目总是会被创建在当前所选的附近 工作表会被创 ...