JAVAWEB项目如何实现验证码

验证码基础

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

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

 

二.图文验证码的原理

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

 

三.验证码所需的技术

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

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

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

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

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

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

 

验证码模块实例

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

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

 

 2.配置Servlet

    在web.xml中的配置如下:

[java] view plaincopy
  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.   
  14.   <servlet-mapping>  
  15.     <servlet-name>PictureCheckCode</servlet-name>  
  16.     <url-pattern>/<SPAN style="COLOR: #ff0000">PictureCheckCode</SPAN></url-pattern>  
  17.   </servlet-mapping>  
  18.   <welcome-file-list>  
  19.     <welcome-file>index.jsp</welcome-file>  
  20.   </welcome-file-list>  
  21. </web-app>  


3.测试验证码

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

    1.index.jsp:显示界面

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


 

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

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


 

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

转载于:https://www.cnblogs.com/jpwpp/p/6255291.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572840.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线判题系统(oj)效果分析图_在线代码编写平台开发分享

计算机专业的大学生应该都了解acm比赛&#xff0c;这种通过使用oj(online judge)系统在线编程刷题&#xff0c;实时反馈学习排名的方式能很大程度激发学生的学习热情。oj学习排名界面oj个人学习记录界面只是oj平台一般都只适用后端语言&#xff0c;如java&#xff0c;c#, c,C&a…

BZOJ1298:[SCOI2009]骰子的学问

Description Input 第一行为两个整数n, m。第二行有n个整数&#xff0c;为a1&#xff0c;a2, …, an。 Output 包含n行&#xff0c;每行m个1~nm的正整数&#xff0c;各不相同&#xff0c;以空格分开。如果有多解&#xff0c;输出任意一组解&#xff1b;如果无解&#xff0c;输出…

mysql索引有字符集_07. 类型、字符集、引擎和索引

字符集是什么&#xff1f;为了更好的识别中文、日文、英文、希腊语。对于常用的符号进行了编码&#xff0c;这个编码就是字符集。字符集确定了文字的存储方式。字符集相当于是计算机中人类的语言。举个例子&#xff1a;我说的是英文&#xff0c;所以我存储的时候要用英文文字来…

new float查询长度 c++_C/C++经典面试题

面试题 1&#xff1a;变量的声明和定义有什么区别 为变量分配地址和存储空间的称为定义&#xff0c;不分配地址的称为声明。一个变量可以在多个地方声明&#xff0c; 但是只在一个地方定义。加入 extern 修饰的是变量的声明&#xff0c;说明此变量将在文件以外或在文件后面部分…

java8--IO(java疯狂讲义3复习笔记)

产生文件 File file new File("abc.txt");if(!file.exists()){System.out.println(file.exists());file.createNewFile();}System.out.println(file.getAbsolutePath()); 关于临时文件 1).放在指定目录,此时已项目为默认目录 File file File.createTempFile("…

python网络平台_python学习(九) 网络编程学习--简易网站服务器

python 网络编程和其他语言都是一样的&#xff0c;服务器这块步骤为&#xff1a;1. 创建套接字2. 绑定地址3. 监听该描述符的所有请求4. 有新的请求到了调用accept处理请求Python Web服务器网关接口(Python Web Server Gateway Interface&#xff0c;简称“WSGI”)&#xff0c;…

rabbit和mysql事务_分布式事务原理及SpringBoot整合RabbitMQ实现可靠事件,TCC事务模型及接口幂等性...

分布式事务我们知道在单数据库系统中&#xff0c;实现数据的一致性&#xff0c;通过数据库的事务来处理比较简单。在微服务或分布式系统中&#xff0c;各个独立的服务都会有自己的数据库&#xff0c;而不是在同一个数据库中&#xff0c;所以当一组事务(如商品交易中&#xff0c…

python pandas 数据库_Python中pandas函数操作数据库

一&#xff1a;创建链接数据库引擎Pythonfrom sqlalchemy import create_engineengine create_engine(postgresql://user58.251.157.179:port/database,echo True)echo True &#xff0c;会显示在加载数据库所执行的SQL语句。12345fromsqlalchemyimportcreate_engineenginecr…

mysql引擎模式_mysql引擎,完整的见表语句,数据库模式, 常用数据类型,约束条件...

引擎show engines : 查看引擎innodb(默认引擎)&#xff1a;支持事务&#xff0c;行级锁&#xff0c;外键myisam:查询效率由于innodb,不需要支持事务&#xff0c;行级锁&#xff0c;外键&#xff0c;可以选用myisam来优化数据库mysql> create table t1(id int)engineinnodb;m…

testng连接MySQL_Selenium+TestNG实战-8-连接数据库方法去验证文章是否发布

原标题&#xff1a;SeleniumTestNG实战-8-连接数据库方法去验证文章是否发布记得之前群里&#xff0c;有人说举例一下连接数据库在Selenium自动化测试中的应用。本篇刚好来举例一个&#xff0c;前面我们都是通过发布后文章的详情页的标题来判断文章是否已经发布成功&#xff0c…

武汉mysql ocp考点_MySQL OCP考试复习系列–开篇:了解MySQL考试

MySQL OCP考试复习系列–开篇&#xff1a;了解MySQL考试嗯&#xff0c;那个决定去考MySQL OCP了&#xff0c;事实上最近工作一直围绕着DB2&#xff0c;MySQL要去考的话需要好好的复习的啊。150分钟&#xff0c;100道多选&#xff0c;答对60道题可以通过&#xff0c;费用1077。L…

java文件服务器_JavaWeb项目架构之NFS文件服务器

NFS简介NFS(Network File System)即网络文件系统。主要功能&#xff1a;通过网络(局域网)让不同的主机系统之间可以共享文件或目录。主要用途&#xff1a;NFS网络文件系统一般被用来存储共享视频&#xff0c;图片&#xff0c;附件等静态资源文件。NFS存储服务无NFS文件共享存储…

table 样式详解

1.table 中css样式控制border 只能控制外边框&#xff0c;内边框需要写<table border"1"> 2.table 会自动撑大&#xff0c;即使td 设置了 width和height这与div 是不同的 3.只有一个table的时候 &#xff0c;高度自适应全屏 <style type"text/css"…

spring整合

spring整合hibernate&#xff0c;整合什么&#xff1f; 1. Spring 整合 Hibernate 整合什么 ?1). 有 IOC 容器来管理 Hibernate 的 SessionFactory 2). 让 Hibernate 使用上 Spring 的声明式事务2. 整合步骤:1). 加入 hibernate ①. jar 包 ②. 添加 hibernate 的配置文件: hi…

看看大货车到底有多少盲区,肯定用得到!救命的!

上路的司机都知道&#xff0c;一旦看到大货车就要离它远远的&#xff0c;因为大货车的盲区大。可是又有多少轿车司机懂得盲区在哪里呢?不仅是轿车司机&#xff0c;许多行人和非机动车辆对于大货车的盲区也是一知半解&#xff0c;常常有人因此丧命。 行人篇 先给大家看一张最直…

msgpack java lua_使用lua-cmsgpack序列化和反序列化lua对象

原文在简书首发&#xff1a;http://www.jianshu.com/p/badf412db4e7lua-cmsgpack是一个开源的MessagePack实现方式、纯C的库&#xff0c;没有任何其它依赖&#xff0c;编译后可以直接被lua调用&#xff0c;目前主要支持Lua5.1/5.2/5.3 版本。1、什么是MessagePack&#xff1f;-…

全国250米DEM数据

全国250米DEM数据 DEM是数字高程模型的英文简称(Digital Elevation Model)&#xff0c;是研究分析地形、流域、地物识别的重要原始资料。由于DEM 数据能够反映一定分辨率的局部地形特征&#xff0c;因此通过DEM 可提取大量的地表形态信息&#xff0c;可用于绘制等高线、坡度图、…

redis集群连接 java_Redis分布式集群和直连的Java客户端调用方式详解

jedis是一个著名的key-value存储系统&#xff0c;而作为其官方推荐的java版客户端jedis也非常强大和稳定&#xff0c;支持事务、管道及有jedis自身实现的分布式。在这里对jedis关于事务、管道和分布式的调用方式做一个简单的介绍和对比&#xff1a;一、普通同步方式最简单和基础…

java爬虫新浪微博_java爬虫(爬新浪新闻) 如何从零开始

爬虫通常搜索引擎处理的对象是互联网网页。首先面临的问题是&#xff1a;如何能够设计出高效的下载系统&#xff0c;以将如此海量的网页数据传送到本地&#xff0c;在本地形成互联网网页的镜像备份。网络爬虫即起此作用&#xff0c;它是搜索引擎系统中很关键也很基础的构件。爬…

CodeVS 1068-乌龟棋

原题 题目描述 Description 小明过生日的时候&#xff0c;爸爸送给他一副乌龟棋当作礼物。 乌龟棋的棋盘是一行N个格子&#xff0c;每个格子上一个分数&#xff08;非负整数&#xff09;。棋盘第1格是唯一 的起点&#xff0c;第N格是终点&#xff0c;游戏要求玩家控制一个乌龟棋…