我们先来看下效果:
(学习视频推荐:java课程)
一、适用需求
后台生成验证码,用于登陆验证。
二、实现流程
1、视图层思路
(1)input用于输入验证码,一个img用于展示验证码
(2)校验输入的验证码是否合格,双击img刷新验证码,绑定onblue失去焦点事件(鼠标失去焦点时触发的事件)
(3)onblue事件中做校验,
(4)img中的src属性值为后台生成验证码的方法请求路径(即requestmapping的路径),当再点击验证码的时候,再动态设置src属性即可(原访问地址+随机时间戳,防止同一路径浏览器不另做访问的问题)
注意:后台直接返回图片,不是验证码的字符!若返回字符,则验证码就失去了意义(前台很容易就可以获取验证码字符,进行多次恶意访问了)(这点考虑了系统安全性)
2、后端思路
利用bufferedimage类创建一张图片,再用graphics2d对图片进行绘制(生成随机字符,添加干扰线)即可,注意:生成的验证码字符串要放到session中,用于接下来登陆的验证码验证(当然也是后台)。
前端代码如下:
<td class="tds">验证码:</td> <td> <input type="text" name="valistr" onblur="checknull('valistr','验证码不能为空!')"> <img id="yzm_img" src="${pagecontext.request.contextpath}/servlet/valiimgservlet" style="cursor: pointer" onclick="changeyzm(this)"/> <span id="valistr_msg"></span> </td> /** * 校验字段是否为空 */ function checknull(name,msg){ setmsg(name,"") var v = document.getelementsbyname(name)[0].value; if(v == ""){ setmsg(name,msg) return false; } return true; } /** * 为输入项设置提示消息 */ function setmsg(name,msg){ var span = document.getelementbyid(name+"_msg"); span.innerhtml="<font color='red'>"+msg+"</font>"; } /** * 点击更换验证码 */ function changeyzm(imgobj){ imgobj.src = "${pagecontext.request.contextpath}/servlet/valiimgservlet?time="+new date().gettime(); }
后端代码如下:
package cn.tedu.web;import cn.tedu.util.verifycode;import javax.servlet.servletexception;import javax.servlet.http.httpservlet;import javax.servlet.http.httpservletrequest;import javax.servlet.http.httpservletresponse;import javax.servlet.http.httpsession;import java.io.ioexception;/** * 获取验证码 */public class valiimgservlet extends httpservlet { protected void dopost(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { //禁止浏览器缓存验证码 response.setdateheader("expires",-1); response.setheader("cache-control","no-cache"); response.setheader("pragma","no-cache"); //生成验证码 verifycode vc = new verifycode(); //输出验证码 vc.drawimage(response.getoutputstream()); //获取验证码的值,存储到session中 string valistr = vc.getcode(); httpsession session = request.getsession(); session.setattribute("valistr",valistr); //打印到控制台 system.out.println(valistr); } protected void doget(httpservletrequest request, httpservletresponse response) throws servletexception, ioexception { dopost(request, response); }}
package cn.tedu.util;import java.awt.color;import java.awt.font;import java.awt.graphics2d;import java.awt.image.bufferedimage;import java.io.file;import java.io.filenotfoundexception;import java.io.fileoutputstream;import java.io.outputstream;import java.util.random;import javax.imageio.imageio;/** * 动态生成图片 */public class verifycode { // {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_gb2312"} private static string[] fontnames = { "宋体", "华文楷体", "黑体", "微软雅黑", "楷体_gb2312" }; // 可选字符 //"23456789abcdefghjkmnopqrstuvwxyzabcdefghjkmnpqrstuvwxyz"; private static string codes = "23456789abcdefghjkmnopqrstuvwxyzabcdefghjkmnpqrstuvwxyz"; // 背景色 private color bgcolor = new color(255, 255, 255); // 基数(一个文字所占的空间大小) private int base = 30; // 图像宽度 private int width = base * 4; // 图像高度 private int height = base; // 文字个数 private int len = 4; // 设置字体大小 private int fontsize = 22; // 验证码上的文本 private string text; private bufferedimage img = null; private graphics2d g2 = null; /** * 生成验证码图片 */ public void drawimage(outputstream outputstream) { // 1.创建图片缓冲区对象, 并设置宽高和图像类型 img = new bufferedimage(width, height, bufferedimage.type_int_rgb); // 2.得到绘制环境 g2 = (graphics2d) img.getgraphics(); // 3.开始画图 // 设置背景色 g2.setcolor(bgcolor); g2.fillrect(0, 0, width, height); stringbuffer sb = new stringbuffer();// 用来装载验证码上的文本 for (int i = 0; i < len; i++) { // 设置画笔颜色 -- 随机 // g2.setcolor(new color(255, 0, 0)); g2.setcolor(new color(getrandom(0, 150), getrandom(0, 150),getrandom(0, 150))); // 设置字体 g2.setfont(new font(fontnames[getrandom(0, fontnames.length)], font.bold, fontsize)); // 旋转文字(-45~+45) int theta = getrandom(-45, 45); g2.rotate(theta * math.pi / 180, 7 + i * base, height - 8); // 写字 string code = codes.charat(getrandom(0, codes.length())) + ""; g2.drawstring(code, 7 + i * base, height - 8); sb.append(code); g2.rotate(-theta * math.pi / 180, 7 + i * base, height - 8); } this.text = sb.tostring(); // 画干扰线 for (int i = 0; i < len + 2; i++) { // 设置画笔颜色 -- 随机 // g2.setcolor(new color(255, 0, 0)); g2.setcolor(new color(getrandom(0, 150), getrandom(0, 150), getrandom(0, 150))); g2.drawline(getrandom(0, 120), getrandom(0, 30), getrandom(0, 120), getrandom(0, 30)); } //todo: g2.setcolor(color.gray); g2.drawrect(0, 0, this.width-1, this.height-1); // 4.保存图片到指定的输出流 try { imageio.write(this.img, "jpeg", outputstream); } catch (exception e) { e.printstacktrace(); throw new runtimeexception(e); }finally{ // 5.释放资源 g2.dispose(); } } /** * 获取验证码字符串 * @return */ public string getcode() { return this.text; } /* * 生成随机数的方法 */ private static int getrandom(int start, int end) { random random = new random(); return random.nextint(end - start) + start; } /*public static void main(string[] args) throws exception { verifycode vc = new verifycode(); vc.drawimage(new fileoutputstream("f:/vc.jpg")); system.out.println("执行成功~!"); }*/}
总结:
简介:是“completely automated public turing test to tell computers and humans apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
历史:是“completely automated public turing test to tell computers and humans apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。
作用:防止恶意破解密码、刷票、论坛灌水、刷页。
分类:gif动画验证码,手机短信验证码,手机语音验证码,视频验证码
常见的验证码:
(1)四位数字和字母,可能都是字母,也可能都是数字,随机的4位字符串,最原始的验证码,验证作用几乎为零。csdn网站用户登录用的是gif格式,常用的随机数字图片验证码。图片上的字符比较中规中矩,验证作用比上一个好。
(2)汉字是注册目前最新的验证码,随机生成,打起来比较难,例如qq申诉页面。
(3)ms的hotmail申请时候的是bmp格式, 随机数字+随机大写英文字母+随机干扰像素+随机位置。
(4)韩文或日文,现在跑跑hf上ms注册要打韩文,增加了难度。
(5)google的gmail注册时候的是jpg格式,随机英文字母+随机颜色+随机位置+随机长度。
(6)其他各大论坛的是xbm格式,内容随机
(7)广告验证码:输入广告中的部分内容即可,特点是可以给网站带来额外收入,也可以使使用者耳目一新。 广告验证码
(8)问题验证码:问题验证码主要是以问答式的形式来进行填写。它的查看比加模验证码更容易辨别和录入,系统可以生成诸如“1+2=?”的问题让用户进行回答,当然这样的问题是随机生成的。另一种问题验证码,则是文字式的问题验证码,诸如生成问题“中国的全称是什么?”,当然有些网站还在问题后面给出了提示答案或直接答案。
相关推荐:java入门
以上就是利用java来生成后台验证码的详细内容。