在Java Web开发中,我们经常需要使用到验证码功能,一般情况下,我们可以将产生的验证码保存到服务器端中的session中,这种方式中,是使用服务器来保证验证码的功能。另外,我们也可以采用js产生验证码。
一、服务器产生验证码
后台服务器产生一个验证码的二进制数据流,直接代码如下:
1 import java.awt.Color; 2 import java.awt.Font; 3 import java.awt.Graphics; 4 import java.awt.Graphics2D; 5 import java.awt.GraphicsEnvironment; 6 import java.awt.Image; 7 import java.awt.geom.AffineTransform; 8 import java.awt.image.BufferedImage; 9 import java.io.IOException; 10 import java.util.ArrayList; 11 import java.util.HashMap; 12 import java.util.List; 13 import java.util.Map; 14 import java.util.Random; 15 16 import javax.imageio.ImageIO; 17 import javax.servlet.http.HttpServletRequest; 18 import javax.servlet.http.HttpServletResponse; 19 20 import net.usitao.common.constants.Constant; 21 import net.usitao.common.constants.ParameterConstants; 22 import net.usitao.common.constants.ResponseCode; 23 import net.usitao.common.util.barcode.Code128Barcode; 24 import net.usitao.model.ResponseObject; 25 26 import org.apache.log4j.Logger; 27 import org.springframework.stereotype.Controller; 28 import org.springframework.web.bind.annotation.RequestMapping; 29 import org.springframework.web.bind.annotation.RequestMethod; 30 import org.springframework.web.bind.annotation.RequestParam; 31 import org.springframework.web.bind.annotation.ResponseBody; 32 33 @Controller 34 public class CodeController extends BasicController { 35 36 private static final long serialVersionUID = 9095917149775028196L; 37 private static final Logger log = Logger.getLogger(CodeController.class); 38 private final static char[] BASIC_CHARACTERS = "qwertyuioplkjhgfdsazxxcvbnm1234567890".toCharArray(); 39 private final static int[] DEFAULT_WORD_COLOR = { 0x000000, 0x292421, 0x708069, 0x4169E1, 0x6A5ACD, 0xFF6100, 0x082E54, 0x385E0F, 0xFF0000, 0x802A2A, 0x8A360F, 0x873324, 0x5E2612, 0x8B4513, 0x0000FF, 0xB0171F, 0xB22222, 0xE3170D, 0x228B22, 0x8A2BE2, 0x0B1746, 0x191970, 0x483D8B, 0x191970 }; 40 private static int WORD_COLOR_SIZE = DEFAULT_WORD_COLOR.length; 41 42 public int codeLength = 4; 43 public int width = 110; 44 public int height = 30; 45 46 @RequestMapping(value = "/code/generate", method = { RequestMethod.GET }) 47 public void generateCode(HttpServletRequest request, HttpServletResponse response) { 48 // 定义图像buffer 49 BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 50 Graphics2D g = buffImg.createGraphics(); 51 52 // 创建一个随机数生成器类 53 Random random = new Random(System.currentTimeMillis()); 54 55 // 将图像填充为白色 56 g.setColor(Color.WHITE); 57 g.fillRect(0, 0, width, height); 58 59 // 画边框。 60 g.setColor(Color.BLACK); 61 g.drawRect(0, 0, width - 1, height - 1); 62 63 // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到。 64 for (int i = 0; i < 20; i++) { 65 int x = random.nextInt(width) - 5; 66 int y = random.nextInt(height) - 5; 67 int xl = random.nextInt(width); 68 int yl = random.nextInt(height); 69 g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255))); 70 g.drawLine(x, y, x + xl, y + yl); 71 } 72 73 // randomCode用于保存随机产生的验证码,以便用户登录后进行验证。 74 StringBuffer randomCode = new StringBuffer(); 75 int x = 10; 76 int y = height - 5; 77 78 g.setColor(Color.BLACK); 79 g.setFont(g.getFont().deriveFont(Font.BOLD, 30f)); 80 81 // 随机产生codeCount数字的验证码。 82 for (int i = 0; i < codeLength; i++) { 83 // 得到随机产生的验证码数字。 84 String strRand = String.valueOf(BASIC_CHARACTERS[random.nextInt(36)]); 85 86 // 用随机产生的颜色将验证码绘制到图像中。 87 g.setColor(new Color(DEFAULT_WORD_COLOR[random.nextInt(WORD_COLOR_SIZE + 1) - 1])); 88 89 /**** 随机缩放文字并将文字旋转指定角度 **/ 90 // 将文字旋转指定角度 91 Graphics2D g2d_word = (Graphics2D) g; 92 AffineTransform trans = new AffineTransform(); 93 //trans.rotate(random.nextInt(30) * 3.14 / 180); 94 // 缩放文字 95 float scaleSize = random.nextFloat() + 0.8f; 96 if (scaleSize > 1.1f) { 97 scaleSize = 1f; 98 } 99 trans.scale(scaleSize, scaleSize); 100 g2d_word.setTransform(trans); 101 /************************/ 102 103 g.drawString(strRand, x, y); 104 x += random.nextInt(10) + 20; 105 106 // 将产生的四个随机数组合在一起。 107 randomCode.append(strRand); 108 } 109 110 // 将四位数字的验证码保存到Session中。 111 request.getSession().setAttribute(Constant.SECURITY_CODE_KEY, randomCode.toString()); 112 g.dispose(); 113 114 try { 115 // 禁止缓存 116 response.setHeader("Pragma", "No-cache"); 117 response.setHeader("Cache-Control", "No-cache"); 118 response.setDateHeader("Expires", 0); 119 // 指定生成的响应是图片 120 response.setContentType("image/jpeg"); 121 ImageIO.write(buffImg, "JPEG", response.getOutputStream()); 122 } catch (IOException e) { 123 log.error("创建验证码失败", e); 124 } 125 } 126 127 @RequestMapping(value = "/code/check", method = { RequestMethod.GET }) 128 @ResponseBody 129 public ResponseObject<Object> checkCode(@RequestParam(value = ParameterConstants.COMMON_VALIDATE_CODE) String vcode, HttpServletRequest request) { 130 if (checkVerifyCode(request, vcode)) { 131 request.getSession().removeAttribute(Constant.SECURITY_CODE_KEY); 132 return new ResponseObject<Object>(ResponseCode.SUCCESS_CODE); 133 } else { 134 return new ResponseObject<Object>(ResponseCode.VALIDATE_CODE_ERROR, "验证码输入错误,请重新输入"); 135 } 136 } 137 }
然后在前台的jsp或者html页面中,像下面这样写就可以了,
1 <img src="code/generate" id="code1" style="cursor: hand;" alt="看不清,换一张" /> 2 3 $("#code1").attr('src','code/generate?timestamp=' + new Date().getTime());
效果是:
二、js端产生验证码
在这里只是简单的写一种实现方式,网上有很多的产生验证码的js库,可以自行下载到项目中使用。
1 var code ; //在全局定义验证码 2 //产生验证码 3 window.onload = function createCode(){ 4 code = ""; 5 var codeLength = 4;//验证码的长度 6 var checkCode = document.getElementById("code"); 7 var random = new Array(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', 8 'S','T','U','V','W','X','Y','Z');//随机数 9 for(var i = 0; i < codeLength; i++) {//循环操作 10 var index = Math.floor(Math.random()*36);//取得随机数的索引(0~35) 11 code += random[index];//根据索引取得随机数加到code上 12 } 13 checkCode.value = code;//把code值赋给验证码 14 } 15 //校验验证码 16 function validate(){ 17 var inputCode = document.getElementById("input").value.toUpperCase(); //取得输入的验证码并转化为大写 18 if(inputCode.length <= 0) { //若输入的验证码长度为0 19 alert("请输入验证码!"); //则弹出请输入验证码 20 } 21 else if(inputCode != code ) { //若输入的验证码与产生的验证码不一致时 22 alert("验证码输入错误!@_@"); //则弹出验证码输入错误 23 createCode();//刷新验证码 24 document.getElementById("input").value = "";//清空文本框 25 } 26 else { //输入正确时 27 alert("^-^"); //弹出^-^ 28 } 29 }
调用js的html写法是:
1 <html> 2 <head> 3 <title>验证码</title> 4 <style type="text/css"> 5 #code 6 { 7 font-family:Arial; 8 font-style:italic; 9 font-weight:bold; 10 border:0; 11 letter-spacing:2px; 12 color:blue; 13 } 14 </style> 15 <script type = "text/javascript" src = "checkCode.js"> 16 </script> 17 </head> 18 <body> 19 <div> 20 <input type = "text" id = "input"/> 21 <input type = "button" id="code" onclick="createCode()"/> 22 <input type = "button" value = "验证" onclick = "validate()"/> 23 </div> 24 </body> 25 </html>