Servlet仿CSDN动态验证码的生成带数字和字母讲解.docx
《Servlet仿CSDN动态验证码的生成带数字和字母讲解.docx》由会员分享,可在线阅读,更多相关《Servlet仿CSDN动态验证码的生成带数字和字母讲解.docx(14页珍藏版)》请在冰豆网上搜索。
![Servlet仿CSDN动态验证码的生成带数字和字母讲解.docx](https://file1.bdocx.com/fileroot1/2022-11/29/72498230-5d7a-4e26-937b-245e784b2401/72498230-5d7a-4e26-937b-245e784b24011.gif)
Servlet仿CSDN动态验证码的生成带数字和字母讲解
Servlet仿CSDN动态验证码的生成-带数字和字母
一、实现的思路:
(1)首先,需要创建一个Servlet。
该Servlet通过字节型响应给客户端返回一个图片,该图片是通过JDK中Java2D的类库来生成一个图片。
图片的生成是依靠一个随机数来完成,然后将这个随机数写成图片格式。
最后在Session将这个随机的字符串的状态保持住,以便在用户填写后进行对比。
(2)其次,在需要加入验证码的JSP页面中,通过引入该图片。
(3)最后,单用户填写完验证码后,提交到某一个Servlet中。
在这个Servlet中,通过request.getParameter()方法获取用户添加的验证码,然后取出后与Session中生成的验证码进行对比,如果对比成功就表示通过,否则返回该页面给用户提示验证码错误的信息。
(4)然后如果要仿CSDN动态验证码,就要分别生成数字和符号(+,-,*),根据符号,计算结果,计算中文,把结果存储到一个List中去。
先来看看效果:
二、代码
这里首先实现只有数字和字母的,还不带符号运算
项目一下载
1、工程整体结构
2、生成带数字和图片的代码
AuthCode.Java
[java]viewplaincopy
packagecom.mucfc;
importjava.awt.Color;
importjava.awt.Graphics;
importjava.awt.Font;
importjava.awt.image.BufferedImage;
importjava.util.Random;
/**
*生成验证码图片
*@author林炳文Evankaka(博客:
*@since2015.6.22
*/
publicclassAuthCode{
publicstaticfinalintAUTHCODE_LENGTH=5;//验证码长度
publicstaticfinalintSINGLECODE_WIDTH=15;//单个验证码宽度
publicstaticfinalintSINGLECODE_HEIGHT=30;//单个验证码高度
publicstaticfinalintSINGLECODE_GAP=4;//单个验证码之间间隔
publicstaticfinalintIMG_WIDTH=AUTHCODE_LENGTH*(SINGLECODE_WIDTH+SINGLECODE_GAP);
publicstaticfinalintIMG_HEIGHT=SINGLECODE_HEIGHT;
publicstaticfinalchar[]CHARS={'0','1','2','3','4','5','6','7','8',
'9','a','b','c','d','e','f','g','h','i','j','k','l','m',
'n','o','p','q','r','s','t','u','v','w','x','y','z',
'A','B','C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
staticRandomrandom=newRandom();
/**
*返回图片中的数字
*@returnString
*/
publicstaticStringgetAuthCode(){
StringBufferbuffer=newStringBuffer();
for(inti=0;i<5;i++){//生成6个字符
buffer.append(CHARS[random.nextInt(CHARS.length)]);
}
returnbuffer.toString();
}
/**
*返回带数字的图片
*@returnBufferedImage
*/
publicstaticBufferedImagegetAuthImg(StringauthCode){
//设置图片的高、宽、类型
//RGB编码:
red、green、blue
BufferedImageimg=newBufferedImage(IMG_WIDTH,IMG_HEIGHT,
BufferedImage.TYPE_INT_BGR);
//得到图片上的一个画笔
Graphicsg=img.getGraphics();
//设置画笔的颜色,用来做背景色
g.setColor(Color.RED);
//用画笔来填充一个矩形,矩形的左上角坐标,宽,高
g.fillRect(0,0,IMG_WIDTH,IMG_HEIGHT);
//将画笔颜色设置为黑色,用来写字
g.setColor(Color.BLACK);
//设置字体:
宋体、不带格式的、字号
g.setFont(newFont("宋体",Font.PLAIN,SINGLECODE_HEIGHT+5));
//输出数字
charc;
for(inti=0;i//取到对应位置的字符
c=authCode.charAt(i);
//画出一个字符串:
要画的内容,开始的位置,高度
g.drawString(c+"",i*(SINGLECODE_WIDTH+SINGLECODE_GAP)
+SINGLECODE_GAP/2,IMG_HEIGHT);
}
Randomrandom=newRandom();
//干扰素
for(inti=0;i<15;i++){
intx=random.nextInt(IMG_WIDTH);
inty=random.nextInt(IMG_HEIGHT);
intx2=random.nextInt(IMG_WIDTH);
inty2=random.nextInt(IMG_HEIGHT);
g.drawLine(x,y,x+x2,y+y2);
}
returnimg;
}
}
在这里还可以自己更改图片的背景色、验证码的个数、干扰素强度等,有兴趣的同学自己好好设置下吧
3、生成动态验证码的servlet
getAuthCodeServlet.java
[java]viewplaincopy
packagecom.mucfc;
importjava.io.IOException;
importjavax.imageio.ImageIO;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
/**
*得到生成验证码图片的servlet
*@author林炳文Evankaka(博客:
*@since2015.6.22
*/
publicclassgetAuthCodeServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
StringauthCode=AuthCode.getAuthCode();
request.getSession().setAttribute("authCode",authCode);//将验证码保存到session中,便于以后验证
try{
//发送图片
ImageIO.write(AuthCode.getAuthImg(authCode),"JPEG",response.getOutputStream());
}catch(IOExceptione){
e.printStackTrace();
}
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
doGet(request,response);
}
}
4、index调用,并进行输入正确的判断
[html]viewplaincopy
<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%
Stringpath=request.getContextPath();
StringbasePath=request.getScheme()+":
//"+request.getServerName()+":
"+request.getServerPort()+path+"/";
%>
DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
">
MyJSP'index.jsp'startingpage
--
-->
看不清
<%
StringinputCode=(String)request.getParameter("inputCode");
StringauthCode=(String)session.getAttribute("authCode");
if(inputCode!
=null){
if(authCode.equalsIgnoreCase(inputCode)){
out.print("验证码正确!
");
}else{
out.print("验证码错误!
请重新输入!
");
}
}
%>
这里在直接都在一个jsp中判断了
5、web.xml设置
[html]viewplaincopy
xmlversion="1.0"encoding="UTF-8"?
>
xmlns="
xmlns:
xsi="http:
//www.w3.org/2001/XMLSchema-instance"
xsi:
schemaLocation="
getAuthCodeServlet
com.mucfc.getAuthCodeServlet
getAuthCodeServlet
/servlet/GetAuthCodeServlet
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
6、运行效果
三、仿CSDN动态验证码实现
整个工程结构不变,
项目二下载
1、AuthCode改成如下
[java]viewplaincopy
packagecom.mucfc;
importjava.awt.Color;
importjava.awt.Graphics;
importjava.awt.Font;
importjava.awt.image.BufferedImage;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Random;
/**
*生成验证码图片
*@author林炳文Evankaka(博客:
*@since2015.6.22
*/
publicclassAuthCode{
publicstaticfinalintAUTHCODE_LENGTH=5;//验证码长度
publicstaticfinalintSINGLECODE_WIDTH=20;//单个验证码宽度
publicstaticfinalintSINGLECODE_HEIGHT=30;//单个验证码高度
publicstaticfinalintSINGLECODE_GAP=4;//单个验证码之间间隔
publicstaticfinalintIMG_WIDTH=AUTHCODE_LENGTH*(SINGLECODE_WIDTH+SINGLECODE_GAP);
publicstaticfinalintIMG_HEIGHT=SINGLECODE_HEIGHT;
publicstaticfinalchar[]CHARS={'0','1','2','3','4','5','6','7','8','9'};
publicstaticfinalchar[]OPERATION={'+','-','*'};
staticRandomrandom=newRandom();
/**
*返回图片中的数字
*@returnString
*/
publicstaticListgetAuthCode(){
charchar1=CHARS[random.nextInt(CHARS.length)];
charchar2=CHARS[random.nextInt(CHARS.length)];
charopt=OPERATION[random.nextInt(OPERATION.length)];
StringBufferbuffer=newStringBuffer();
buffer.append(char1);
buffer.append(getOperation(opt));
buffer.append(char2);
Stringresult=getResult(char1,char2,opt);
Listlist=newArrayList();
list.add(buffer.toString());
list.add(result);
returnlist;
}
/**
*返回计算的结果
*@paramoperation
*@returnString
*/
publicstaticStringgetResult(charchar1,charchar2,charoperation){
intint1=Integer.parseInt(String.valueOf(char1));
intint2=Integer.parseInt(String.valueOf(char2));
if('+'==operation)
returnString.valueOf(int1+int2);
elseif('-'==operation)
returnString.valueOf(int1-int2);
elseif('*'==operation)
returnString.valueOf(int1*int2);
else
returnnull;
}
/**
*返回符号对应的中文
*@paramoperation
*@returnString
*/
publicstaticStringgetOperation(charoperation){
if('+'==operation)
return"加上";
elseif('-'==operation)
return"减去";
elseif('*'==operation)
return"乘以";
else
returnnull;
}
/**
*返回带数字的图片
*@returnBufferedImage
*/
publicstaticBufferedImagegetAuthImg(StringauthCode){
//设置图片的高、宽、类型
//RGB编码:
red、green、blue
BufferedImageimg=newBufferedImage(IMG_WIDTH,IMG_HEIGHT,
BufferedImage.TYPE_INT_BGR);
//得到图片上的一个画笔
Graphicsg=img.getGraphics();
//设置画笔的颜色,用来做背景色
g.setColor(Color.YELLOW);
//用画笔来填充一个矩形,矩形的左上角坐标,宽,高
g.fillRect(0,0,IMG_WIDTH,IMG_HEIGHT);
//将画笔颜色设置为黑色,用来写字
g.setColor(Color.BLACK);
//设置字体:
宋体、不带格式的、字号
g.setFont(newFont("宋体",Font.PLAIN,SINGLECODE_HEIGHT+5));
//输出数字
charc;
for(inti=0;i//取到对应位置的字符
c=authCode.charAt(i);
//画出一个字符串:
要画的内容,开始的位置,高度
g.drawString(c+"",i*(SINGLECODE_WIDTH+SINGLECODE_GAP)
+SINGLECODE_GAP/2,IMG_HEIGHT);
}
Randomrandom=newRandom();
//干扰素
for(inti=0;i<5;i++){
intx=random.nextInt(IMG_WIDTH);
inty=random.nextInt(IMG_HEIGHT);
intx2=random.nextInt(IMG_WIDTH);
inty2=random.nextInt(IMG_HEIGHT