验证码基础

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

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

二.图文验证码的原理

:在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. 判断横屏竖屏,然后CSS重新计算

    function hengshuping(){ if(window.orientation==180||window.orientation==0){ alert("竖屏状态!") ...

  2. Android 自动化测试—robotium(九) Junit_report测试报告重定向输出到终端SDCard

    借鉴网上相关资料主要用于无root权限的终端.主要分为以下三步: 一.重写InstrumentationTestRunner类: package com.exmaple.test; import ja ...

  3. 清华学堂 Range

    Descriptioin Let S be a set of n integral points on the x-axis. For each given interval [a, b], you ...

  4. [转]passport.js学习笔记

    概述 passport.js是Nodejs中的一个做登录验证的中间件,极其灵活和模块化,并且可与Express.Sails等Web框架无缝集成.Passport功能单一,即只能做登录验证,但非常强大, ...

  5. 服务端的GET、POST请求

    一.HttpClient方式,程序集 System.Net.Http.dll GET: HttpClient httpClient = new HttpClient(); string result ...

  6. 我JSP学习心得1

    老师布置了一项作业,说是要按着老师的要求写,但我觉得只要是技术分享的心得就是好的,不论是不是所要求的内容. 由于和几个人在外面给别人搭建网站,项目需要学习了jsp有用到了javascript,这里有一 ...

  7. How To Handle a Loss of Confidence in Yourself

    Do you feel like you've lost confidence in yourself? Have you had strong self doubts? Perhaps you we ...

  8. 保护眼睛(ubuntu 和 chrome)

    chrome 安插件https://chrome.google.com/webstore/detail/%E4%BF%9D%E6%8A%A4%E7%9C%BC%E7%9D%9B/fgadnbmmoln ...

  9. CSS3过渡、变形和动画

    1.CSS3过渡 所谓CSS3过渡,就是使用CSS3让元素从一种状态慢慢转换到另一种状态.如鼠标的悬停状态就是一种过渡.如下例子: #content a{     text-decoration: n ...

  10. java设计模式

    五种创建型模式: 1.工厂模式 普通工厂模式: 工厂类提供一个方法可以生产多种实现了某种接口的类 多方法工厂模式: 一个方法对应一个要生产的类 静态工厂模式: 静态方法来生产类 2.抽象工厂模式 工厂 ...