以前跟着写的一段获取验证码的servlet,当时觉得还挺麻烦的要自己画,最近找到了一个封装好的工具类记录一下
先看看以前写的获取验证码的servlet
package cn.itcast.travel.web.servlet; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; /** * 验证码 */ @WebServlet("/checkCode") public class CheckCodeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { //服务器通知浏览器不要缓存 response.setHeader("pragma","no-cache"); response.setHeader("cache-control","no-cache"); response.setHeader("expires","0"); //在内存中创建一个长80,宽30的图片,默认黑色背景 //参数一:长 //参数二:宽 //参数三:颜色 int width = 80; int height = 30; BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //获取画笔 Graphics g = image.getGraphics(); //设置画笔颜色为灰色 g.setColor(Color.GRAY); //填充图片 g.fillRect(0,0, width,height); //产生4个随机验证码,12Ey String checkCode = getCheckCode(); //将验证码放入HttpSession中 request.getSession().setAttribute("CHECKCODE_SERVER",checkCode); //设置画笔颜色为黄色 g.setColor(Color.YELLOW); //设置字体的小大 g.setFont(new Font("黑体",Font.BOLD,24)); //向图片上写入验证码 g.drawString(checkCode,15,25); //将内存中的图片输出到浏览器 //参数一:图片对象 //参数二:图片的格式,如PNG,JPG,GIF //参数三:图片输出到哪里去 ImageIO.write(image,"PNG",response.getOutputStream()); } /** * 产生4位随机字符串 */ private String getCheckCode() { String base = "0123456789ABCDEFGabcdefg"; int size = base.length(); Random r = new Random(); StringBuffer sb = new StringBuffer(); for(int i=1;i<=4;i++){ //产生0到size-1的随机值 int index = r.nextInt(size); //在base字符串中获取下标为index的字符 char c = base.charAt(index); //将c放入到StringBuffer中去 sb.append(c); } return sb.toString(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request,response); } }
下面是工具类 返回值是一个String 类型的code 还有一个BufferedImage image 对象
在Controller层用ImageIO.write(image,"png",response.getOutputStream)返回,把code存入Session中
package com.mkx_test.utils; import java.awt.*; import java.awt.image.BufferedImage; import java.util.Random; public class CodeImageUtil { private static final char[] chars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; // 字符数量 private static final int SIZE = 4; // 干扰线数量 private static final int LINES = 5; // 宽度 private static final int WIDTH = 100; // 高度 private static final int HEIGHT = 40; // 字体大小 private static final int FONT_SIZE = 30; public static Object[] createImage(){ StringBuffer sb = new StringBuffer(); //创建空白图片 BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB); //获取图片画笔 Graphics graphics = image.getGraphics(); //设置画笔颜色 graphics.setColor(new Color(0xEDEDED)); //绘制矩形背景 graphics.fillRect(0,0,WIDTH,HEIGHT); //画随机字符 Random random = new Random(); for (int i=0;i<SIZE;i++){ //获取随机字符索引 int j = random.nextInt(chars.length); //设置随机颜色 graphics.setColor(getRandonColor()); //设置字体大小 graphics.setFont(new Font(null,Font.BOLD+Font.ITALIC,FONT_SIZE)); //画字符 graphics.drawString(chars[j] + "",i * (WIDTH)/SIZE + 1,HEIGHT*2/3); //记录字符 sb.append(chars[j]); } //画干扰线 for (int i = 0;i<LINES;i++){ //设置随机颜色 graphics.setColor(getRandonColor()); //随机画线 graphics.drawLine(random.nextInt(WIDTH),random.nextInt(HEIGHT),random.nextInt(WIDTH),random.nextInt(HEIGHT)); } //返回验证码和图片 return new Object[]{sb.toString(),image}; } /** * 随机取色 */ private static Color getRandonColor() { Random random = new Random(); Color color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256)); return color; } // public static void main(String[] args) throws IOException { // Object[] objs = createImage(); // BufferedImage image = (BufferedImage) objs[1]; // OutputStream os = new FileOutputStream("d:/1.png"); // ImageIO.write(image, "png", os); // os.close(); // } }
Controller层中
/* * 加载验证码 */ @RequestMapping("/getCode") public void getCode(HttpServletRequest request,HttpServletResponse response) throws IOException { Object[] objs = CodeImageUtil.createImage(); String code = objs[0].toString(); System.out.println("系统生成的验证码是:"+code); //image对象 BufferedImage image =(BufferedImage) objs[1]; //将内存中的图片输出到浏览器 //参数一:图片对象 //参数二:图片的格式,如PNG,JPG,GIF //参数三:图片输出到哪里去 ImageIO.write(image,"png",response.getOutputStream()); request.getSession().setAttribute("code",code); }
视图层jsp中:注意加上点击事件的时间戳,每次都能换到不同的验证码图片
<div class="form-group"> <label for="codeInp">验证码</label> <input type="text" id="codeInp" name="code" > <img id="code" src="${pageContext.request.contextPath}/user/getCode" onclick="flushCode(this)"> </div> <script> function flushCode(obj) { let time = new Date().getTime(); obj.src="${pageContext.request.contextPath}/user/getCode?"+time; } </script>