做注册登陆需要图片验证码。
遂如下
package com.dtyunxi.jingbo.common.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.util.Random; import com.dtyunxi.jingbo.common.utils.redis.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("imageCode") public class ImageCode { private int width = 125; private int height = 38; private int codeLength = 4; private String randomString = "ABCDEFGHIJKLMNPQRSTUVWXYZ23456789abcdefghijkmnpqrstuvwxyz"; private String sessionKey = "SESSION_VCODE"; private String fontName = "Times New Roman"; private int fontStyle = 0; private int fontSize = 18; private Long expireTime = 900L;// 15分钟 protected static final Logger logger = LoggerFactory.getLogger(ImageCode.class); private static final String IMGCODESTR = "imgCode:"; @Autowired private RedisUtil redisManager; /* * 根据sessionId绑定图片验证码 */ public BufferedImage getImageWithSessionId(String keyCode) { // 在内存中创建图象 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 生成随机类 Random random = new Random(); // 设定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width, height); // 设定字体 g.setFont(new Font(fontName, fontStyle, fontSize)); g.setColor(getRandColor(160, 200)); for (int i = 0; i < 155; i++) { int x = random.nextInt(width); int y = random.nextInt(height); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); } String sRand = randomRand(codeLength);// 取随机产生的认证码 int strWidth = width / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength - 24; int strHeight = height / 2 + 12; for (int i = 0; i < codeLength; i++) { String rand = sRand.substring(i, i + 1); // 将认证码显示到图象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同, int zz = new Random().nextInt(8); zz = zz % 2 == 0 ? zz - 10 : zz; g.drawString(rand, strWidth + (13 + 16 * i), strHeight + zz); } //request.getSession().setAttribute(sessionKey, sRand); g.dispose(); return image; } /* * 根据sessionId绑定图片验证码 */ public BufferedImage getImageWithSessionId(Integer width_, Integer height_, Integer fontSize_, Integer codeLength_) { width_ = width_ == null ? width : width_; height_ = height_ == null ? height : height_; fontSize_ = fontSize_ == null ? fontSize : fontSize_; codeLength_ = codeLength_ == null ? codeLength : codeLength_; // 在内存中创建图象 BufferedImage image = new BufferedImage(width_, height_, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 生成随机类 Random random = new Random(); // 设定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width_, height_); // 设定字体 Font f = new Font(fontName, fontStyle, fontSize_); g.setFont(f); g.setColor(getRandColor(160, 200)); for (int i = 0; i < 155; i++) { int x = random.nextInt(width_); int y = random.nextInt(height_); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); } String sRand = randomRand(codeLength_);// 取随机产生的认证码 int strWidth = width_ / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength_ - fontSize_; int strHeight = height_ / 2 + g.getFontMetrics(f).getHeight() / 4; for (int i = 0; i < codeLength_; i++) { String rand = sRand.substring(i, i + 1); // 将认证码显示到图象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同, g.drawString(rand, 13 * i + 6 + strWidth, strHeight); } //request.getSession().setAttribute(sessionKey, sRand); g.dispose(); return image; } /* * 根据前端随机生成一个code码绑定图片验证码放在redis * */ public BufferedImage getImage(Integer width_, Integer height_, Integer fontSize_, Integer codeLength_, String imageKey) { width_ = width_ == null ? width : width_; height_ = height_ == null ? height : height_; fontSize_ = fontSize_ == null ? fontSize : fontSize_; codeLength_ = codeLength_ == null ? codeLength : codeLength_; // 在内存中创建图象 BufferedImage image = new BufferedImage(width_, height_, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics g = image.getGraphics(); // 生成随机类 Random random = new Random(); // 设定背景色 g.setColor(getRandColor(200, 250)); g.fillRect(0, 0, width_, height_); // 设定字体 Font f = new Font(fontName, fontStyle, fontSize_); g.setFont(f); g.setColor(getRandColor(160, 200)); for (int i = 0; i < 155; i++) { int x = random.nextInt(width_); int y = random.nextInt(height_); int xl = random.nextInt(12); int yl = random.nextInt(12); g.drawLine(x, y, x + xl, y + yl); } String sRand = randomRand(codeLength_);// 取随机产生的认证码 int strWidth = width_ / 2 - g.getFontMetrics().stringWidth(sRand) / codeLength_ - fontSize_; int strHeight = height_ / 2 + g.getFontMetrics(f).getHeight() / 4; for (int i = 0; i < codeLength_; i++) { String rand = sRand.substring(i, i + 1); // 将认证码显示到图象中 g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调用函数出来的颜色相同, g.drawString(rand, 13 * i + 6 + strWidth, strHeight); } // 干扰线 /* int lines = 2; for (int i = 0; i < lines; i++) { Color c = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)); g.setColor(c); g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height)); }*/ String key = getKey(imageKey); redisManager.set(key, sRand, expireTime); g.dispose(); return image; } public String getImageCode(String imageKey) { String key = getKey(imageKey); String values = redisManager.get(key); return values; } public void cleanImageCode(String imageKey) { String key = getKey(imageKey); redisManager.remove(key); } private String getKey(String imageKey) { return IMGCODESTR + imageKey; } private Color getRandColor(int fc, int bc) {// 给定范围获得随机颜色 Random random = new Random(); if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } private String randomRand(int n) { String rand = ""; int len = randomString.length() - 1; double r; for (int i = 0; i < n; i++) { r = (Math.random()) * len; rand = rand + randomString.charAt((int) r); } return rand; } }这是工具类。
@Autowired private ImageCode imageCode;
/** * 校验图片验证码 * @param imgCodeVO * @return */ public ResponseDTO validImageCode(ImgCodeVO imgCodeVO){ String code = imageCode.getImageCode(imgCodeVO.getImageKey()); if (StringUtils.isEmpty(code)) { return new ResponseDTO(false, ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_info(), ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_no()); } // 不区分大小写 Boolean isPass = code.equalsIgnoreCase(imgCodeVO.getImageCode()); if (isPass) { // 验证失败,重新获取新的,就得验证码马上失效 imageCode.cleanImageCode(imgCodeVO.getImageKey()); return new ResponseDTO(true); } return new ResponseDTO(true); } /** * 获取图片验证码 * @return */ public ResponseDTO getImageCode(){ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); String imageStr; UUID uuid = UUID.randomUUID(); String imageKey = uuid.toString(); try { ImageIO.write(imageCode.getImage(125, 38, 18, 4, imageKey), "png", outputStream); imageStr = com.alibaba.druid.util.Base64.byteArrayToBase64(outputStream.toByteArray()); //String imageStr = Base64.encodeBase64String(outputStream.toByteArray()); } catch (IOException e) { return new ResponseDTO(false, ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_info(), ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_no()); } finally { if (null != outputStream) { try { outputStream.close(); } catch (IOException e) { return new ResponseDTO(false, ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_info(), ErrorInfos.ClientErr.VERIFYCODE_TOME_OUT.getError_no()); } } } ImgCodeDTO imgCodeDTO = new ImgCodeDTO(); imgCodeDTO.setImageKey(imageKey); imgCodeDTO.setImageCodeBase(imageStr); return new ResponseDTO(imgCodeDTO); }