以前碰到注册登录需要图形验证码的时候,一般都是到网络上直接淘一个,也不读代码,直接就用了,今天静下来,从头到尾读了一遍代码,自己又照着写了一遍,加上了完整的注释,下面介绍步骤,首先新建一个web项目,src新建一个class类:
1 import java.awt.BasicStroke; 2 import java.awt.Color; 3 import java.awt.Font; 4 import java.awt.Graphics; 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 public class VCode { 16 17 private int w;// 图片宽 18 private int h;// 图片高 19 private Color bgColor = new Color(240, 240, 240);// 背景色 20 private Random random = new Random();// 随机数对象 21 // 设置字体范围 22 private String[] fontNames = { "宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", 23 "楷体" }; 24 //设置字体样式范围 25 private int[] fontstyles = { 0, 1, 2, 3 }; 26 //设置字号范围 27 private int[] fontSizes={24,25,26,27,28}; 28 //设置所有字符串范围 29 private String codes="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 30 31 32 //无参构造方法 33 public VCode() { 34 } 35 36 //带宽和高的构造函数 37 public VCode(int w, int h) { 38 super(); 39 this.w = w; 40 this.h = h; 41 } 42 43 44 // 返回一张背景图片 45 private BufferedImage createImage() { 46 /** 47 * 1:创建图片 2:设置背景色 48 */ 49 // 1:创建图片 50 BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); 51 // 2:设置背景色 52 Graphics g = img.getGraphics(); 53 g.setColor(bgColor); 54 g.fillRect(0, 0, w, h); 55 56 return img; 57 } 58 59 // 随机返回字体颜色 60 private Color randomColor() { 61 int r = random.nextInt(256); 62 int g = random.nextInt(256); 63 int b = random.nextInt(256); 64 return new Color(r, g, b); 65 } 66 67 // 随机返回字体样式 68 private Font randomFont() { 69 //随机生成字体下标,随机从给定的范围内获取一个字体 70 int index=random.nextInt(fontNames.length); 71 String name=fontNames[index]; 72 73 //随机生成字体样式下表,随机从给定的返回内获取到一个字体样式 74 index=random.nextInt(fontstyles.length); 75 int style = fontstyles[index]; 76 77 //随机生成字体大小下标,随机从给定的返回内获取到一个字体大小 78 index=random.nextInt(fontSizes.length); 79 int size = fontSizes[index]; 80 81 return new Font(name, style, size); 82 } 83 84 // 随机返回字体内容 85 private String randomChar() { 86 int index=random.nextInt(codes.length()); 87 88 return codes.charAt(index)+""; 89 } 90 91 //随即返回几条干扰线 92 private void getLine(BufferedImage img){ 93 //设置干扰线的宽度为1.5倍宽,随机画五条 94 Graphics2D g=(Graphics2D)img.getGraphics(); 95 g.setColor(Color.BLACK); 96 g.setStroke(new BasicStroke(1.5f)); 97 for(int i=0;i<5;i++){ 98 int x1=random.nextInt(w); 99 int y1=random.nextInt(h);100 int x2=random.nextInt(w);101 int y2=random.nextInt(h);102 g.drawLine(x1, y1, x2, y2);103 104 }105 106 }107 // 用户调用该方法获取图片108 public BufferedImage getImage() {109 /**110 * 随机生成字符,字符范围0-9A-Za-z, 设置字体,字号,是否粗体 都是随机 字符的颜色111 */112 BufferedImage img = createImage();113 114 this.getLine(img);115 // 获取画笔116 Graphics g = img.getGraphics();117 // 画内容118 for (int i = 0; i < 4; i++) {119 g.setColor(this.randomColor());// 获取随机颜色120 g.setFont(this.randomFont());// 获取随机字体121 g.drawString(this.randomChar(), w / 4 * i, h - 5);// 获取字符串随机内容122 }123 return img;124 }125 126 //用户调用该方法保存图片到本地127 public void saveImage(BufferedImage img,OutputStream ous){128 129 try {130 ImageIO.write(img, "JPEG", ous);131 } catch (FileNotFoundException e) {132 e.printStackTrace();133 } catch (IOException e) {134 e.printStackTrace();135 }136 }137 }接下来新建一个servlet:
1 package com.wang.verifySode; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.image.BufferedImage; 7 import java.io.FileOutputStream; 8 import java.io.IOException; 9 import java.io.PrintWriter;10 11 import javax.imageio.ImageIO;12 import javax.servlet.ServletException;13 import javax.servlet.http.HttpServlet;14 import javax.servlet.http.HttpServletRequest;15 import javax.servlet.http.HttpServletResponse;16 17 public class BServlet extends HttpServlet {18 19 public void doGet(HttpServletRequest request, HttpServletResponse response)20 throws ServletException, IOException {21 22 VCode v=new VCode(70, 35);23 BufferedImage img=v.getImage();24 v.saveImage(img, response.getOutputStream());25 26 }27 28 }在你需要加验证码的地方,如注册页面中适当地方加入:
<img id="img" alt="" src="/tools/BServlet"><a href="javascript:changeNext()">看不清楚,换一张</a>这里需要说一下,因为验证码有一个"看不清楚 换一张"的功能,所以需要加一个javascript函数,如下:
<script type="text/javascript"> function changeNext(){ var a=document.getElementById("img"); a.src="/tools/BServlet?a="+new Date().getTime(); }</script>为了避免浏览器的图片缓存问题而导致点击后无法随机下一张图片,这里在超链接后面加一个永不重复的参数,可以避免这个问题,见上面代码.
配置项目,开浏览器,运行,完美~
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。


