Spring框架生成图片验证码实例
程序员文章站
2024-03-13 20:33:27
这篇文章会从前台页面到后台实现完整的讲解,下面跟着小编一起来看看。
1、前台的代码,image.jsp
<%@ page language="java"...
这篇文章会从前台页面到后台实现完整的讲解,下面跟着小编一起来看看。
1、前台的代码,image.jsp
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>获取图片验证码</title> <script type="text/javascript" src="${pagecontext.request.contextpath }/static/js/jquery-1.10.2.min.js"></script> </head> <body> <form action="##" method='post'> <input type="hidden" id="userid" name="userid" value=""> <div class="form-group"> <div class="email controls"> <input type="text" name='loginname' id="loginname" placeholder="用户名" value="" class='form-control'/> </div> </div> <div class="form-group"> <div class="pw controls"> <input type="password" autocomplete="off" id="pwd" name="pwd" placeholder="密码" class='form-control'/> </div> </div> <div class="form-group"> <div class="email controls"> <input id="validatecode" onblur="checkimg(this.value)" name="validatecode" type="text" class="form-control" placeholder="输入验证码"/> </div> <span class="y_yzimg"><img id="codevalidateimg" onclick="javascript:flushvalidatecode();"/></span> <p class="y_change"><a href="javascript:flushvalidatecode();" >换一张</a></p> </div> <div class="form-group"> <span class="text-danger"></span> </div> <div class="submit"> <div class="remember"> <input type="checkbox" name="remember" value="1" class='icheck-me' data-skin="square" data-color="blue" id="remember"> <label for="remember">记住我</label> </div> <input type="button" value="登录" onclick="javascript:submitform();" class='btn btn-primary'> </div> </form> <script type="text/javascript"> $(document).ready(function() { flushvalidatecode();//进入页面就刷新生成验证码 }); /* 刷新生成验证码 */ function flushvalidatecode(){ var validateimgobject = document.getelementbyid("codevalidateimg"); validateimgobject.src = "${pagecontext.request.contextpath }/getsysmanagelogincode?time=" + new date(); } /*校验验证码输入是否正确*/ function checkimg(code){ var url = "${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
package com.dufyun.springmvc.web.controller; import javax.servlet.http.cookie; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.springframework.stereotype.controller; import org.springframework.util.stringutils; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.responsebody; import com.dufy.javaweb.test.randomvalidatecode; @controller public class imagegencontroller { @requestmapping(value="/toimg") public string toimg(){ return "image/image"; } //登录获取验证码 @requestmapping("/getsysmanagelogincode") @responsebody public string getsysmanagelogincode(httpservletresponse response, httpservletrequest request) { 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); randomvalidatecode randomvalidatecode = new randomvalidatecode(); try { randomvalidatecode.getrandcode(request, response,"imagecode");// 输出图片方法 } catch (exception e) { e.printstacktrace(); } return ""; } //验证码验证 @requestmapping(value = "/checkimagecode") @responsebody public string checktcode(httpservletrequest request,httpservletresponse response) { string validatecode = request.getparameter("validatecode"); string code = null; //1:获取cookie里面的验证码信息 cookie[] cookies = request.getcookies(); for (cookie cookie : cookies) { if ("imagecode".equals(cookie.getname())) { code = cookie.getvalue(); break; } } //1:获取session验证码的信息 //string code1 = (string) request.getsession().getattribute(""); //2:判断验证码是否正确 if(!stringutils.isempty(validatecode) && validatecode.equals(code)){ return "ok"; } return "error"; //这里我没有进行字母大小模糊的验证处理,感兴趣的你可以去试一下! } }
3、生成验证码的工具类randomvalidatecode.java
package com.dufy.javaweb.test; import java.awt.color; import java.awt.font; import java.awt.graphics; import java.awt.image.bufferedimage; import java.io.bytearrayoutputstream; import java.util.random; import javax.imageio.imageio; import javax.servlet.http.cookie; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; public class randomvalidatecode { private random random = new random(); private string randstring = "0123456789abcdefghijklmnopqrstuvwxyz";// 随机产生的字符串 private int width = 80;// 图片宽 private int height = 26;// 图片高 private int linesize = 40;// 干扰线数量 private int stringnum = 4;// 随机产生字符数量 /* * 获得字体 */ private font getfont() { return new font("fixedsys", font.center_baseline, 18); } /* * 获得颜色 */ private color getrandcolor(int fc, int bc) { if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextint(bc - fc - 16); int g = fc + random.nextint(bc - fc - 14); int b = fc + random.nextint(bc - fc - 18); return new color(r, g, b); } /* * 绘制字符串 */ private string drowstring(graphics g, string randomstring, int i) { g.setfont(getfont()); g.setcolor(new color(random.nextint(101), random.nextint(111), random .nextint(121))); string rand = string.valueof(getrandomstring(random.nextint(randstring .length()))); randomstring += rand; g.translate(random.nextint(3), random.nextint(3)); g.drawstring(rand, 13 * i, 16); return randomstring; } /* * 绘制干扰线 */ private void drowline(graphics g) { int x = random.nextint(width); int y = random.nextint(height); int xl = random.nextint(13); int yl = random.nextint(15); g.drawline(x, y, x + xl, y + yl); } /* * 获取随机的字符 */ public string getrandomstring(int num) { return string.valueof(randstring.charat(num)); } /** * 生成随机图片 */ public void getrandcode(httpservletrequest request,httpservletresponse response,string key) { // bufferedimage类是具有缓冲区的image类,image类是用于描述图像信息的类 bufferedimage image = new bufferedimage(width, height,bufferedimage.type_int_bgr); graphics g = image.getgraphics();// 产生image对象的graphics对象,改对象可以在图像上进行各种绘制操作 g.fillrect(0, 0, width, height); g.setfont(new font("times new roman", font.roman_baseline, 18)); g.setcolor(getrandcolor(110, 133)); // 绘制干扰线 for (int i = 0; i <= linesize; i++) { drowline(g); } // 绘制随机字符 string randomstring = ""; for (int i = 1; i <= stringnum; i++) { randomstring = drowstring(g, randomstring, i); } //1:将随机生成的验证码放入cookie中 cookie cookie = new cookie(key,randomstring); response.addcookie(cookie); //2:将随机生成的验证码放入session中 string sessionid = request.getsession().getid(); request.getsession().setattribute(sessionid+key, randomstring); system.out.println("*************" + randomstring); //总结:这两种方式都是很好, //(1):使用cookie的方式,将验证码发送到前台浏览器,不安全!不建议使用。 //(2):使用session的方式,虽然能解决验证码不发送到浏览器,安全性较高了,但是如果用户量太大,这样的存储方式会对服务器造成压力,影响服务器的性能。不建议使用。 //这里暂时实现用这种方式,好的办法是,在项目中使用的缓存,将生成的验证码存放到缓存中,设置失效时间,这样既可以实现安全性也能减轻服务器的压力。 g.dispose(); try { bytearrayoutputstream tmp = new bytearrayoutputstream(); imageio.write(image, "png", tmp); tmp.close(); integer contentlength = tmp.size(); response.setheader("content-length", contentlength + ""); response.getoutputstream().write(tmp.tobytearray());// 将内存中的图片通过流动形式输出到客户端 } catch (exception e) { e.printstacktrace(); }finally{ try { response.getoutputstream().flush(); response.getoutputstream().close(); } catch (exception e2) { e2.printstacktrace(); } } } }
4、总结
本文的内容到这就结束了,如果对里面的地方有不懂的地方,可以留言讨论。希望本文的内容对大家的学习工作能有所帮助。