一、什么是图片验证码?
可以参考下面这张图:
我们在一些网站注册的时候,经常需要填写以上图片的信息。
1、图片生成实体类:
1 package com.hexianwei.graphic; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics2D; 6 import java.awt.image.BufferedImage; 7 import java.io.FileNotFoundException; 8 import java.io.FileOutputStream; 9 import java.io.IOException; 10 import java.io.OutputStream; 11 import java.util.Random; 12 13 import javax.imageio.ImageIO; 14 15 16 public class ImageVerificationCode { 17 18 private int weight = 100; //验证码图片的长和宽 19 private int height = 40; 20 private String text; //用来保存验证码的文本内容 21 private Random r = new Random(); //获取随机数对象 22 //private String[] fontNames = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"}; //字体数组 23 //字体数组 24 private String[] fontNames = {"Georgia"}; 25 //验证码数组 26 private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; 27 28 /** 29 * 获取随机的颜色 30 * 31 * @return 32 */ 33 private Color randomColor() { 34 int r = this.r.nextInt(225); //这里为什么是225,因为当r,g,b都为255时,即为白色,为了好辨认,需要颜色深一点。 35 int g = this.r.nextInt(225); 36 int b = this.r.nextInt(225); 37 return new Color(r, g, b); //返回一个随机颜色 38 } 39 40 /** 41 * 获取随机字体 42 * 43 * @return 44 */ 45 private Font randomFont() { 46 int index = r.nextInt(fontNames.length); //获取随机的字体 47 String fontName = fontNames[index]; 48 int style = r.nextInt(4); //随机获取字体的样式,0是无样式,1是加粗,2是斜体,3是加粗加斜体 49 int size = r.nextInt(10) + 24; //随机获取字体的大小 50 return new Font(fontName, style, size); //返回一个随机的字体 51 } 52 53 /** 54 * 获取随机字符 55 * 56 * @return 57 */ 58 private char randomChar() { 59 int index = r.nextInt(codes.length()); 60 return codes.charAt(index); 61 } 62 63 /** 64 * 画干扰线,验证码干扰线用来防止计算机解析图片 65 * 66 * @param image 67 */ 68 private void drawLine(BufferedImage image) { 69 int num = r.nextInt(10); //定义干扰线的数量 70 Graphics2D g = (Graphics2D) image.getGraphics(); 71 for (int i = 0; i < num; i++) { 72 int x1 = r.nextInt(weight); 73 int y1 = r.nextInt(height); 74 int x2 = r.nextInt(weight); 75 int y2 = r.nextInt(height); 76 g.setColor(randomColor()); 77 g.drawLine(x1, y1, x2, y2); 78 } 79 } 80 81 /** 82 * 创建图片的方法 83 * 84 * @return 85 */ 86 private BufferedImage createImage() { 87 //创建图片缓冲区 88 BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB); 89 //获取画笔 90 Graphics2D g = (Graphics2D) image.getGraphics(); 91 //设置背景色随机 92 g.setColor(new Color(255, 255, r.nextInt(245) + 10)); 93 g.fillRect(0, 0, weight, height); 94 //返回一个图片 95 return image; 96 } 97 98 /** 99 * 获取验证码图片的方法 100 * 101 * @return 102 */ 103 public BufferedImage getImage() { 104 BufferedImage image = createImage(); 105 Graphics2D g = (Graphics2D) image.getGraphics(); //获取画笔 106 StringBuilder sb = new StringBuilder(); 107 for (int i = 0; i < 4; i++) //画四个字符即可 108 { 109 String s = randomChar() + ""; //随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画 110 sb.append(s); //添加到StringBuilder里面 111 float x = i * 1.0F * weight / 4; //定义字符的x坐标 112 g.setFont(randomFont()); //设置字体,随机 113 g.setColor(randomColor()); //设置颜色,随机 114 g.drawString(s, x, height - 5); 115 } 116 this.text = sb.toString(); 117 drawLine(image); 118 return image; 119 } 120 121 /** 122 * 获取验证码文本的方法 123 * 124 * @return 125 */ 126 public String getText() { 127 return text; 128 } 129 130 public static void output(BufferedImage image, OutputStream out) throws IOException //将验证码图片写出的方法 131 { 132 ImageIO.write(image, "JPEG", out); 133 } 134 }
2、在控制器中把图片响应给前端页面
1 @RequestMapping("getVerifiCode") 2 @ResponseBody 3 public void getVerifiCode(HttpServletRequest request, HttpServletResponse response) throws IOException { 4 /* 5 1.生成验证码 6 2.把验证码上的文本存在session中 7 3.把验证码图片发送给客户端 8 */ 9 ImageVerificationCode ivc = new ImageVerificationCode(); //用我们的验证码类,生成验证码类对象 10 BufferedImage image = ivc.getImage(); //获取验证码 11 request.getSession().setAttribute("text", ivc.getText()); //将验证码的文本存在session中 12 ivc.output(image, response.getOutputStream());//将验证码图片响应给客户端 13 }
3、从session获得验证码字符
1 @RequestMapping("Login_authentication") 2 @ResponseBody 3 public String Login_authentication(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException { 4 request.setCharacterEncoding("utf-8"); 5 String session_vcode=(String) request.getSession().getAttribute("text"); //从session中获取真正的验证码 6 return session_vcode; 7 }
4、前端请求图片
1 <a href="javascript:getVerifiCode()"> 2 <img id="yzm_img" style="cursor:pointer;width: 100px;height: 36px;margin: 5px 0 0 5px;border-radius: 3px;" title="点击刷新验证码" src="Mcake/getVerifiCode"/> 3 </a> 4 function getVerifiCode() { 5 $("#yzm_img").prop('src','Mcake/getVerifiCode?a='+new Date().getTime()); 6 }