Spring框架生成图片验证码实例
这篇文章会从前台页面到后台实现完整的讲解,下面跟着小编一起来看看。
1、前台的代码,image.jsp
<%@pagelanguage="java"contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=UTF-8">
<title>获取图片验证码</title>
<scripttype="text/javascript"src="${pageContext.request.contextPath}/static/js/jquery-1.10.2.min.js"></script>
</head>
<body>
<formaction="##"method='post'>
<inputtype="hidden"id="userId"name="userId"value="">
<divclass="form-group">
<divclass="emailcontrols">
<inputtype="text"name='loginName'id="loginName"placeholder="用户名"value=""class='form-control'/>
</div>
</div>
<divclass="form-group">
<divclass="pwcontrols">
<inputtype="password"autocomplete="off"id="pwd"name="pwd"placeholder="密码"class='form-control'/>
</div>
</div>
<divclass="form-group">
<divclass="emailcontrols">
<inputid="validateCode"onblur="checkImg(this.value)"name="validateCode"type="text"class="form-control"placeholder="输入验证码"/>
</div>
<spanclass="y_yzimg"><imgid="codeValidateImg"onClick="javascript:flushValidateCode();"/></span>
<pclass="y_change"><ahref="javascript:flushValidateCode();">换一张</a></p>
</div>
<divclass="form-group">
<spanclass="text-danger"></span>
</div>
<divclass="submit">
<divclass="remember">
<inputtype="checkbox"name="remember"value="1"class='icheck-me'data-skin="square"data-color="blue"id="remember">
<labelfor="remember">记住我</label>
</div>
<inputtype="button"value="登录"onclick="javascript:submitForm();"class='btnbtn-primary'>
</div>
</form>
<scripttype="text/javascript">
$(document).ready(function(){
flushValidateCode();//进入页面就刷新生成验证码
});
/*刷新生成验证码*/
functionflushValidateCode(){
varvalidateImgObject=document.getElementById("codeValidateImg");
validateImgObject.src="${pageContext.request.contextPath}/getSysManageLoginCode?time="+newDate();
}
/*校验验证码输入是否正确*/
functioncheckImg(code){
varurl="${pageContext.request.contextPath}/checkimagecode";
$.get(url,{"validateCode":code},function(data){
if(data=="ok"){
alert("ok!")
}else{
alert("error!")
flushValidateCode();
}
})
}
</script>
</body>
</html>
2、后台代码ImageGenController.java
packagecom.dufyun.springmvc.web.controller;
importjavax.servlet.http.Cookie;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.springframework.stereotype.Controller;
importorg.springframework.util.StringUtils;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.ResponseBody;
importcom.dufy.javaweb.test.RandomValidateCode;
@Controller
publicclassImageGenController{
@RequestMapping(value="/toImg")
publicStringtoImg(){
return"image/image";
}
//登录获取验证码
@RequestMapping("/getSysManageLoginCode")
@ResponseBody
publicStringgetSysManageLoginCode(HttpServletResponseresponse,
HttpServletRequestrequest){
response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片
response.setHeader("Pragma","No-cache");//设置响应头信息,告诉浏览器不要缓存此内容
response.setHeader("Cache-Control","no-cache");
response.setHeader("Set-Cookie","name=value;HttpOnly");//设置HttpOnly属性,防止Xss攻击
response.setDateHeader("Expire",0);
RandomValidateCoderandomValidateCode=newRandomValidateCode();
try{
randomValidateCode.getRandcode(request,response,"imagecode");//输出图片方法
}catch(Exceptione){
e.printStackTrace();
}
return"";
}
//验证码验证
@RequestMapping(value="/checkimagecode")
@ResponseBody
publicStringcheckTcode(HttpServletRequestrequest,HttpServletResponseresponse){
StringvalidateCode=request.getParameter("validateCode");
Stringcode=null;
//1:获取cookie里面的验证码信息
Cookie[]cookies=request.getCookies();
for(Cookiecookie:cookies){
if("imagecode".equals(cookie.getName())){
code=cookie.getValue();
break;
}
}
//1:获取session验证码的信息
//Stringcode1=(String)request.getSession().getAttribute("");
//2:判断验证码是否正确
if(!StringUtils.isEmpty(validateCode)&&validateCode.equals(code)){
return"ok";
}
return"error";
//这里我没有进行字母大小模糊的验证处理,感兴趣的你可以去试一下!
}
}
3、生成验证码的工具类RandomValidateCode.java
packagecom.dufy.javaweb.test;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
importjava.awt.image.BufferedImage;
importjava.io.ByteArrayOutputStream;
importjava.util.Random;
importjavax.imageio.ImageIO;
importjavax.servlet.http.Cookie;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassRandomValidateCode{
privateRandomrandom=newRandom();
privateStringrandString="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生的字符串
privateintwidth=80;//图片宽
privateintheight=26;//图片高
privateintlineSize=40;//干扰线数量
privateintstringNum=4;//随机产生字符数量
/*
*获得字体
*/
privateFontgetFont(){
returnnewFont("Fixedsys",Font.CENTER_BASELINE,18);
}
/*
*获得颜色
*/
privateColorgetRandColor(intfc,intbc){
if(fc>255)
fc=255;
if(bc>255)
bc=255;
intr=fc+random.nextInt(bc-fc-16);
intg=fc+random.nextInt(bc-fc-14);
intb=fc+random.nextInt(bc-fc-18);
returnnewColor(r,g,b);
}
/*
*绘制字符串
*/
privateStringdrowString(Graphicsg,StringrandomString,inti){
g.setFont(getFont());
g.setColor(newColor(random.nextInt(101),random.nextInt(111),random
.nextInt(121)));
Stringrand=String.valueOf(getRandomString(random.nextInt(randString
.length())));
randomString+=rand;
g.translate(random.nextInt(3),random.nextInt(3));
g.drawString(rand,13*i,16);
returnrandomString;
}
/*
*绘制干扰线
*/
privatevoiddrowLine(Graphicsg){
intx=random.nextInt(width);
inty=random.nextInt(height);
intxl=random.nextInt(13);
intyl=random.nextInt(15);
g.drawLine(x,y,x+xl,y+yl);
}
/*
*获取随机的字符
*/
publicStringgetRandomString(intnum){
returnString.valueOf(randString.charAt(num));
}
/**
*生成随机图片
*/
publicvoidgetRandcode(HttpServletRequestrequest,HttpServletResponseresponse,Stringkey){
//BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
Graphicsg=image.getGraphics();//产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
g.fillRect(0,0,width,height);
g.setFont(newFont("TimesNewRoman",Font.ROMAN_BASELINE,18));
g.setColor(getRandColor(110,133));
//绘制干扰线
for(inti=0;i<=lineSize;i++){
drowLine(g);
}
//绘制随机字符
StringrandomString="";
for(inti=1;i<=stringNum;i++){
randomString=drowString(g,randomString,i);
}
//1:将随机生成的验证码放入Cookie中
Cookiecookie=newCookie(key,randomString);
response.addCookie(cookie);
//2:将随机生成的验证码放入session中
Stringsessionid=request.getSession().getId();
request.getSession().setAttribute(sessionid+key,randomString);
System.out.println("*************"+randomString);
//总结:这两种方式都是很好,
//(1):使用cookie的方式,将验证码发送到前台浏览器,不安全!不建议使用。
//(2):使用session的方式,虽然能解决验证码不发送到浏览器,安全性较高了,但是如果用户量太大,这样的存储方式会对服务器造成压力,影响服务器的性能。不建议使用。
//这里暂时实现用这种方式,好的办法是,在项目中使用的缓存,将生成的验证码存放到缓存中,设置失效时间,这样既可以实现安全性也能减轻服务器的压力。
g.dispose();
try{
ByteArrayOutputStreamtmp=newByteArrayOutputStream();
ImageIO.write(image,"png",tmp);
tmp.close();
IntegercontentLength=tmp.size();
response.setHeader("content-length",contentLength+"");
response.getOutputStream().write(tmp.toByteArray());//将内存中的图片通过流动形式输出到客户端
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
response.getOutputStream().flush();
response.getOutputStream().close();
}catch(Exceptione2){
e2.printStackTrace();
}
}
}
}
4、总结
本文的内容到这就结束了,如果对里面的地方有不懂的地方,可以留言讨论。希望本文的内容对大家的学习工作能有所帮助。