jsp实现验证码
在web开发领域里面,验证码是一个比较常见的功能,而归根到底,验证码其实就是一组随机数,或者是一个随机算术
一、基本知识
1、为什么需要验证码?
验证码,很多时候出现在注册页面或者登陆界面,在这些页面中有可能会出现恶意注册和暴力破解,这时候验证码可以有效防范这些攻击。所以,总的来说,验证码很多时候是为了防止不法分子对网站进行恶意的注册和攻击,是一种有效的拦截手段。
2、验证码的工作原理
首先,我们要明确一点就是,验证码实际是在服务器端产生的,因为如果在前端参数的话并不能有效拦截,因此很多时候,在拦截时我们都需要在服务器端进行相关操作,防止黑客绕过前端验证直接非法访问。
验证码的工作原理其实方几个步骤:首先,服务端随机产生几个随机数或者随机算式,然后通过session对象将数据传输到客户端,客户端输入验证码,通过r表单将数据提交到服务器,服务器提取数据之后和产生的随机数字或者算式的结果对比,以此进行验证。
当然,很多时候,简单的验证码很容易被图像识别软件破解,所以现在很多时候更流行短信验证等方式,但是,一下讨论的均是简单的数字图片验证。
二、验证码的实现过程
1、首先,验证码其实就是在服务端产生一张带有验证码数字或者算式的图片,所以,在这个过程要用到gui知识,具体请先看一下代码
//1、验证码界面
//验证码的宽和高
int width = 70;
int height = 30;
/*
*图像缓冲对象(注意:在多次对某个对象操作时,为了提高效率,很多时候选择用缓冲对象来进行操作,
因为缓冲类的对象很多时候是可以即时改变对象的数据的)
*/
BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//创建图像操作对象,用于操作验证码图片对象
Graphics2D g = bufferedImage.createGraphics();
//创建字体对象方便操作图像字体的属性
Font font = new Font("Times New Roman",Font.PLAIN,18);
g.setFont(font);
//设置相关颜色等等
g.setColor(Color.BLACK);
g.drawRect(0,0,width-1,height-1);
g.setColor(Color.GRAY);
以上创建了一个基本的验证码图片,注意很多时候如果要反复对象对某个对象进行修改操作时(如某个字符串,需要反复进行拼接操作时,为提高性能,一般选择用缓冲类的对象进行操作之后再转换为相关对象)。以上是产生验证码的gui主要代码,具体的步骤不啰嗦了,请参考代码吧。
2、创建好相关的验证码图片界面之后,下一步就是产生随机数了,请先看以下代码:
//2、产生随机数
//定义生成随机数的对象
Random random = new Random();
//产生干扰线
for(int i=0;i<40;i++){
//设置40条干扰线
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(10);
int y2 = random.nextInt(10);
//将随机线条描绘到验证码对象中
g.drawLine(x1,y1,x1+x2,y1+y2);
}
//产生随机数
//定义随机数的个数
int length = 4
//定义 变量存储随机数字变量
BufferedString str_random = new BufferedString();//定义成缓冲字符类型是为了提高效率
for(int i=0;i<length;i++){
int num_random = random.nextInt(10);
String str_num = String.valueOf(num_random);
g.drawString(str_num);
str_random.append(str_num);
}
以上主要通过Random随机数产生对象来产生随机数字,其中注意要在反复第String类型操作的时候,将其定义成BufferedString进行操作比较高效。具体的操作并没有涉及什么新技术,请查看代码。
3、完成产生随机数的步骤之后,剩下的就是将产生的随机数发送出去了。请看代码
//3、发送验证码图片数据
bufferedImg.flush();//刷新与图像缓冲有关的数据
g.dispose();//释放与Graphice2D有关的对象的资源
String randomCode = str_random.toString();
session.setAttribute("randomCode",randomCode.toString());//通过session传递随机码给其他页面用于验证身份
ServletOutputStream outputStream = response.getOutputStream();
ImageIO.write(bufferedImg,"jpeg",outputStream); outputStream.close(); out.clear();
out=pageContext.pushBody();
以上的发送验证码也是比较简单,只是通过网络流进行发送操作,其中,注意Graphics2D的资源释放和IO流的关闭就好了。其中,将验证码通过session发送给其他页面使用。
三、总结
以上实现了简单的数字验证码功能,其中涉及到的技术主要是javaGUI、IO操作和servlet技术的session技术。类似的,实现算式的验证码也是类似的步骤,具体的就不多说,下面的代码是实现了简单的算式验证码的代码参考:
int width = 70,height = 22;
if(request.getParameter("width")!=null){
try{
width=Integer.parseInt(request.getParameter("width"));
}catch(NumberFormatException e) { }
}
BufferedImage bufferedImg = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D g = bufferedImg.createGraphics(); g.setColor(Color.WHITE);
g.fillRect(0,0,width,height); Font font = new Font("Times New Roman",Font.PLAIN,18);
g.setFont(font); g.setColor(Color.BLACK);
g.drawRect(0,0,width-1,height-1);
g.setColor(Color.GRAY); Random random = new Random();//设置随机种子 for(int i=0;i<40;i++){
//设置40条干扰线
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
int x2 = random.nextInt(10);
int y2 = random.nextInt(10);
g.drawLine(x1,y1,x1+x2,y1+y2);
} int length = 4;//设置默认生成四个长度的验证码
if(request.getParameter("length")!=null){
try{
length = Integer.parseInt(request.getParameter("length"));
}catch(NumberFormatException e){
out.println("<script>alert('无法加载验证码,请重新操作!')</script");
e.printStackTrace();
}
}
//定义变量存储运算结果
int result = 0;
//定义一个int用于存储某个数字后面的运算符,1代表+,2代表-,初始化为0
int int_sign = 0;
for(int i = 0;i<length;i++){//获取随机数字字符串
int num_random = random.nextInt(10);
//根据符号标记标量int_sign进行相应的运算
if(int_sign==2){
result = result - num_random;
}else{
result = result + num_random;
}
String strRand = String.valueOf(num_random);
g.setColor(Color.RED);
g.drawString(strRand,13 * i + 6, 16);
//随机获取运算符号
if(i<length-1){
int sign_random = random.nextInt(2);
if(sign_random<1){
g.setColor(Color.GREEN);
g.drawString("+",13 * i + 12, 16);
int_sign = 1;
}else{
g.setColor(Color.BLUE);
g.drawString("-",13 * i + 12, 16);
int_sign = 2;
}
}else{
g.drawString("=?",13 * i + 12, 16);
} }
bufferedImg.flush();
g.dispose(); session.setAttribute("randomCode",result); response.setContentType("image/jpeg");
response.setHeader("Pragam","no-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires",0); ServletOutputStream outputStream = response.getOutputStream();
ImageIO.write(bufferedImg,"jpeg",outputStream); outputStream.close(); out.clear();
out=pageContext.pushBody();
好了,验证码的总结就到此结束,有什么不足的地方请各位大神指正!
jsp实现验证码的更多相关文章
- 使用jsp生成验证码
在开发中验证码是比较常用到有效防止这种问题对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试的方式. 此演示程序包括三个文件: 1.index.jsp:登录页面 2.image.jsp:生成 ...
- Jsp制作验证码
验证码 验证码(CAPTCHA)是"Completely Automated Public Turing test to tell Computers and Humans Apart&qu ...
- jsp页面验证码(完整实例)
项目结构如下,MyEclipse中新建一个Web Project,取名servlet 1.src下new一个servlet类 package com.servlet; import java.awt. ...
- jsp实现验证码登陆
login.jsp: <%@ page language="java" import="java.util.*,com.cn.servlet.*" pag ...
- jsp 生成验证码代码
调用方法:在jsp页面用图像标签便可以直接调用如下是标签代码<img border=0 src="image.jsp">,只需要把该代码发在验证码要显示的区域就可以了) ...
- Jsp+servlet 验证码案例
昨晚在csdn看到一位前辈写一个ajax+servlet+jsp验证.顿时心血来潮,在阅读前辈的代码下我亲手体验一下,做了一个验证码生成工具类.以供大家做个參考. 1:加入VeriyCodeUtils ...
- JSP页面验证码实现
首先在JSP页面加上生成图片的链接 <img type="image" src="auth/authCode" id="codeImage&qu ...
- jsp的验证码实现
package com.xunfang.demo; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; imp ...
- JSP生成验证码
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%&g ...
随机推荐
- Spring配置数据源的几种形式
Spring中提供了4种不同形式的数据源配置方式: 1.Spring自带的数据源(DriverMangerDataSource); 2.DBCP数据源; 3.C3P0数据源; 4.JNDI数据源. 以 ...
- Java中XML格式的字符串4读取方式的简单比较
Java中XML格式的字符串4读取方式的简单比较 1.java自带的DOM解析. import java.io.StringReader; import javax.xml.parsers.Docum ...
- 01背包问题:POJ3624
背包问题是动态规划中的经典问题,而01背包问题是最基本的背包问题,也是最需要深刻理解的,否则何谈复杂的背包问题. POJ3624是一道纯粹的01背包问题,在此,加入新的要求:输出放入物品的方案. 我们 ...
- 《深入理解Spark:核心思想与源码分析》正式出版上市
自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...
- 关于把A表中的数据复制到B表中(整理)
如果A,B两个表中没有重复数据且表结构一样可以直接 insert into B select * from A 如果结构不一样可以 insert into B(字段列表),select 字段列表 fr ...
- Python批量修改文件名
处理语料库时,有些文件名字很不规则,为了方便处理,同义按数字顺序修改名称,主要是用到os模块: import os def RenameFiles(srcdir): #将目录下所有的文件命名为数字开头 ...
- fgets和fputs函数
1 函数输入 下面两个函数提供每次输入一行的功能. #include <stdio.h> char *fgets( char *restrict buf, int n, FILE *res ...
- H3C ipsec ike 协商配置
1. 分几步设置 (1)定义ACL (2)创建 ipsec 安全建议 1.选择认证方式 ah 选择 ah头认证方式 不配置 ipsec不能建立成功 (3)创建IKE keychain 可以写多条key ...
- Delphi 的字符及字符串[6] - Char(AnsiChar)、WideChar 与其编码的相互转换
); ); {返回: A } c := Char($41); {返回: A }end; ]; ); ); {万} c := WideChar($4E07); {万}end ...
- Dynamic CRM 2013学习笔记(二十七)无代码 复制/克隆方法
前面介绍过二种复制/克隆方法:<Dynamic CRM 2013学习笔记(十四)复制/克隆记录> 和<Dynamic CRM 2013学习笔记(二十五)JS调用web service ...