Java实现随机验证码和验证码图片渲染功能
0.注意事项:
- 图片格式(宽、高)、干扰线及数量在工具类的成员变量配置
- 验证码验证。验证码生成后是存储在session中的,使用相同的属性名(类似key)即可取出,然后进行比对
1. 验证码生成工具类
package com.jbp.util;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/** * @ClassName: OptimizeVerificationCodeUtil * @description: 验证码生产工具类优化版 * @author: JiangBeiPing * @create: 2021-05-12 10:12 * @Version: 1.0 **/
public class OptimizeVerificationCodeUtil {
/** * 验证码图片 */
private BufferedImage image;
/** * 验证码 */
private String verificationCode;
/** * 生成的验证码的类型(目前的业务类型只需要数字类型) */
private static char[] codeSequence = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
/** * 存入Session的验证码的属性名称 */
public static final String SESSION_VERIFICATION_CODE = "validateCode";
/** * 设置验证码图片的宽度 */
private static final int WIDTH = 600;
/** * 设置验证码图片的高度 */
private static final int HEIGHT = 200;
/** * 设置验证码字符的个数 */
private static final int CODE_COUNT = 4;
/** * 设置验证码图片干扰线的数量 */
private static final int INTERFERING_LINE_COUNT = 160;
private OptimizeVerificationCodeUtil() {
// 初始化过程中生产并渲染验证码图片
init();
}
/** * 对外提供的本工具类的实例 * * @return 工具类的实例 */
public static OptimizeVerificationCodeUtil instance() {
return new OptimizeVerificationCodeUtil();
}
/** * 获取验证码图片 * * @return 验证码图片 */
public BufferedImage getImage() {
return this.image;
}
/** * 获取验证码 * * @return 验证码 */
public String getVerificationCode() {
return this.verificationCode;
}
private void init() {
// 在内存中创建验证码图片
BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// 获取图形上下文
Graphics2D graphics = bufferedImage.createGraphics();
try {
// 随机数生成器类
Random random = new Random();
// 图像背景设置为白色
graphics.setColor(Color.white);
graphics.fillRect(0, 0, WIDTH, HEIGHT);
// 创建字体,字体的大小应该根据图片的高度来定
Font font = new Font("Fixedsys", Font.PLAIN, HEIGHT - 2);
// 设置字体
graphics.setFont(font);
// 画边框
graphics.setColor(Color.BLACK);
graphics.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
// 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到
for (int i = 0; i < INTERFERING_LINE_COUNT; i++) {
// 每条干扰线都设置为随机颜色
graphics.setColor(getRandomColor());
int x2 = random.nextInt(WIDTH);
int y2 = random.nextInt(HEIGHT);
int x1 = random.nextInt(WIDTH);
int y1 = random.nextInt(HEIGHT);
graphics.drawLine(x2, y2, x2 + x1, y2 + y1);
}
// randomCode用于保存随机产生的验证码,以便用户登录后进行验证
StringBuilder randomCode = new StringBuilder();
int x = WIDTH / (CODE_COUNT + 1);
int codeY = HEIGHT - 4;
// 随机产生 codeCount 数字的验证码
for (int i = 0; i < CODE_COUNT; i++) {
// 获取随机产生的验证码数字
String strRand = String.valueOf(codeSequence[random.nextInt(10)]);
// 用随机产生的颜色将验证码绘制到图像中
graphics.setColor(getRandomColor());
graphics.drawString(strRand, (i + 1) * x, codeY);
// 将产生的四个随机数组合在一起
randomCode.append(strRand);
}
// 赋值验证码
this.verificationCode = String.valueOf(randomCode);
// 赋值图像
this.image = bufferedImage;
} finally {
// 不关闭的话有OOM风险
graphics.dispose();
}
}
/** * 生成随机颜色 * @return 随机颜色 */
private static Color getRandomColor() {
Random random = new Random();
return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}
}
2. Controller层
package com.jbp.controller;
import com.jbp.util.OptimizeVerificationCodeUtil;
import com.jbp.util.VerificationCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Map;
/** * @ClassName: VerificationCodeController * @description: 验证码Controller * @author: JiangBeiPing * @create: 2021-05-11 11:28 * @Version: 1.0 **/
@RequestMapping("/verification")
@RestController
@Slf4j
public class VerificationCodeController {
@RequestMapping(value = "/getSecurityCode", produces = { "application/json;charset=UTF-8"},method = RequestMethod.GET)
public void getSecurityCode(HttpServletResponse response, HttpServletRequest request){
// 通知浏览器不要缓存
response.setHeader("Expires","-1");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "-1");
// 将验证码输入到session中,用来验证
OptimizeVerificationCodeUtil optimizeVerificationCodeUtil = OptimizeVerificationCodeUtil.instance();
String verificationCode = optimizeVerificationCodeUtil.getVerificationCode();
request.getSession().setAttribute(OptimizeVerificationCodeUtil.SESSION_VERIFICATION_CODE,verificationCode);
try {
ImageIO.write(optimizeVerificationCodeUtil.getImage(), "jpg", response.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
3. 效果测试
ps:无视水印,问就是在划水
还没有评论,来说两句吧...