SpringMVC下获取验证码实例详解
SpringMVC下获取验证码实例详解
前言:
1.用户一开始登录的时候,不建议出现验证码,这一点在很多网站上已经体现的很好了,只有当用户连续输错三次或者以上才会要求用户输入验证码.
2.记录用户输错次数最好不要使用session来记录,因为session是跟客户端浏览器会话有关的,如果用重启浏览器或者换新的浏览器再来登录或者试错,就是新的回话了,原来记录的错误次数就失效了.建议此处采用缓存机制来实现,简单处理就是采用Map<用户登录id,错误次数>来实现,如果有多台服务器负载的话,就需要采用另外的缓存机制,比如采用Redis.
3.当用户输入完用户名以后,就需要用登录名进行判断,是否需要进行验证码校验.
4.生成的验证码与session绑定,是否需要校验验证码,要根据用户规定时间内失败的次数来判断.
原生的servlet可以直接write图片到客户端.但是刚用springMVC的童鞋可能不知道怎么在此框架下返回图片.其实在本质上用spring返回图片跟用servlet是一样的。都是使用的HttpServletResponse来返回图片.
springMVC的controller里获取验证码的方法
/**
*生成验证码
*@paramrequest
*@paramresponse
*/
@RequestMapping(value="login/getVerifyCode")
publicvoidgetVerifyCode(HttpServletRequestrequest,HttpServletResponseresponse){
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires",0);
response.setContentType("image/jpeg");
//生成随机字符串
StringverifyCode=VerifyCodeUtils.generateVerifyCode(4);
//存入Session,此处可以根据自己的需求
HttpSessionsession=request.getSession();
session.setAttribute("verifyCode",verifyCode);
//生成图片
intw=100,h=35;
try{
//将图片写入到response的输出流即可将图片返回到客户端了
VerifyCodeUtils.outputImage(w,h,response.getOutputStream(),verifyCode);
}catch(IOExceptione){
logger.error("生成验证码失败,Causeby:{}",e.getMessage(),e);
}
}
生成验证码图片的类
网上找到的一个,还不错.
importjavax.imageio.ImageIO;
importjava.awt.*;
importjava.awt.geom.AffineTransform;
importjava.awt.image.BufferedImage;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
importjava.util.Arrays;
importjava.util.Random;
/**
*生成图片流
*@Description:Createdbyzcqshineon2017/5/18.
*/
publicclassVerifyCodeUtils{
privatestaticfinalStringVERIFY_CODES="23456789ABCDEFGHJKLMNPQRSTUVWXYZ";
privatestaticRandomrandom=newRandom();
/**
*使用系统默认字符源生成验证码
*@paramverifySize验证码长度
*@return
*/
publicstaticStringgenerateVerifyCode(intverifySize){
returngenerateVerifyCode(verifySize,VERIFY_CODES);
}
/**
*使用指定源生成验证码
*@paramverifySize验证码长度
*@paramsources验证码字符源
*@return
*/
publicstaticStringgenerateVerifyCode(intverifySize,Stringsources){
if(sources==null||sources.trim().length()==0){
sources=VERIFY_CODES;
}
intcodesLen=sources.length();
Randomrand=newRandom(System.currentTimeMillis());
StringBuilderverifyCode=newStringBuilder(verifySize);
for(inti=0;i255)
fc=255;
if(bc>255)
bc=255;
intr=fc+random.nextInt(bc-fc);
intg=fc+random.nextInt(bc-fc);
intb=fc+random.nextInt(bc-fc);
returnnewColor(r,g,b);
}
privatestaticintgetRandomIntColor(){
int[]rgb=getRandomRgb();
intcolor=0;
for(intc:rgb){
color=color<<8;
color=color|c;
}
returncolor;
}
privatestaticint[]getRandomRgb(){
int[]rgb=newint[3];
for(inti=0;i<3;i++){
rgb[i]=random.nextInt(255);
}
returnrgb;
}
privatestaticvoidshear(Graphicsg,intw1,inth1,Colorcolor){
shearX(g,w1,h1,color);
shearY(g,w1,h1,color);
}
privatestaticvoidshearX(Graphicsg,intw1,inth1,Colorcolor){
intperiod=random.nextInt(2);
booleanborderGap=true;
intframes=1;
intphase=random.nextInt(2);
for(inti=0;i>1)
*Math.sin((double)i/(double)period
+(6.2831853071795862D*(double)phase)
/(double)frames);
g.copyArea(0,i,w1,1,(int)d,0);
if(borderGap){
g.setColor(color);
g.drawLine((int)d,i,0,i);
g.drawLine((int)d+w1,i,w1,i);
}
}
}
privatestaticvoidshearY(Graphicsg,intw1,inth1,Colorcolor){
intperiod=random.nextInt(40)+10;//50;
booleanborderGap=true;
intframes=20;
intphase=7;
for(inti=0;i>1)
*Math.sin((double)i/(double)period
+(6.2831853071795862D*(double)phase)
/(double)frames);
g.copyArea(i,0,1,h1,0,(int)d);
if(borderGap){
g.setColor(color);
g.drawLine(i,(int)d,i,0);
g.drawLine(i,(int)d+h1,i,h1);
}
}
}
publicstaticvoidmain(String[]args){
Filedir=newFile("/Users/zcqshine/Downloads/test");
intw=200,h=80;
for(inti=0;i<50;i++){
StringverifyCode=generateVerifyCode(4);
Filefile=newFile(dir,verifyCode+".jpg");
try{
outputImage(w,h,file,verifyCode);
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!如有疑问请留言或到本站社区交流讨论,大家共同进步!