一、概述
如上图,在登录页面上,除了输入用户名和密码之外,有时候需要输入验证码,那么验证的功能可以怎么实现呢?
二、实现过程
1、工具类
public class CaptchaUtil {
/** 验证码源 */
public static final String CAPTHCHA_CODES = "23456789adcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
/** 验证码位数 */
public static final Integer CAPTCHA_SIZE = 4;
private static Random random = new Random();
/**
* 使用系统默认字符源生成验证码
*
* @param captchaSize 验证码长度
* @return 验证码
*/
public static String generateCaptcha(int captchaSize) {
return generateCaptcha(captchaSize, CAPTHCHA_CODES);
}
/**
* 使用指定源生成验证码
*
* @param captchaSize 验证码长度
* @param sources 验证码字符源
* @return 验证码
*/
public static String generateCaptcha(int captchaSize, String sources) {
if (sources == null || sources.length() == 0) {
sources = CAPTHCHA_CODES;
}
int codesLen = sources.length();
Random rand = new Random(System.currentTimeMillis());
StringBuilder captcha = new StringBuilder(captchaSize);
for (int i = 0; i < captchaSize; i++) {
captcha.append(sources.charAt(rand.nextInt(codesLen - 1)));
}
return captcha.toString();
}
/**
* 输出随机验证码图片流,并返回验证码值
*
* @param w 宽度
* @param h 高度
* @param os 输出流
* @param captchaSize 验证码长度
* @return
* @throws IOException
*/
public static String outputCaptchaImage(int w, int h, OutputStream os, int captchaSize) throws IOException {
String captcha = generateCaptcha(captchaSize);
outputImage(w, h, os, captcha);
return captcha;
}
/**
* 输出指定验证码图片流
*
* @param w 宽度
* @param h 高度
* @param os 输出流
* @param captcha 验证码
* @throws IOException
*/
public static void outputImage(int w, int h, OutputStream os, String captcha) throws IOException {
BufferedImage image = generateBufferedImage(w, h, captcha);
ImageIO.write(image, "jpg", os);
}
public static BufferedImage generateBufferedImage(int w, int h, String code) {
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 设置背景色
g2.setColor(getRandColor(200, 250));
g2.fillRect(0, 0, w, h);
// 设置线条的颜色
g2.setColor(getRandColor(160, 200));
for (int i = 0; i < 10; i++) {
int x = random.nextInt(w - 1);
int y = random.nextInt(h - 1);
int xl = random.nextInt(6) + 1;
int yl = random.nextInt(12) + 1;
// 绘制干扰线
g2.drawLine(x, y, x + xl + 40, y + yl + 20);
}
// 添加噪点
float yawpRate = 0.02f; // 噪声率
int area = (int) (yawpRate * w * h);
for (int i = 0; i < area; i++) {
int x = random.nextInt(w);
int y = random.nextInt(h);
int rgb = getRandomIntColor();
image.setRGB(x, y, rgb);
}
// 设置验证码
g2.setColor(getRandColor(100, 160));
int fontSize = h - 4;
Font font = new Font("Algerian", Font.ITALIC, fontSize);
g2.setFont(font);
char[] chars = code.toCharArray();
int length = code.length();
for (int i = 0; i < length; i++) {
AffineTransform affine = new AffineTransform();
affine.setToRotation(Math.PI / 4 * random.nextDouble() * (random.nextBoolean() ? 1 : -1),
(w / length) * i + fontSize / 2, h / 2);
g2.setTransform(affine);
g2.drawChars(chars, i, 1, ((w - 10) / length) * i + 5, h / 2 + fontSize / 2 - 5);
}
g2.dispose();
return image;
}
private static Color getRandColor(int fc, int bc) {
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 static int getRandomIntColor() {
int[] rgb = getRandomRgb();
int color = 0;
for (int c : rgb) {
color = color << 8;
color = color | c;
}
return color;
}
private static int[] getRandomRgb() {
int[] rgb = new int[3];
for (int i = 0; i < 3; i++) {
rgb[i] = random.nextInt(255);
}
return rgb;
}
}
2、服务端控制器调用方式
@ApiOperation(value = "生成验证码")
@GetMapping("/generateCaptcha")
public void generateCaptcha(HttpServletResponse response) {
try {
OutputStream os = response.getOutputStream();
response.setContentType("image/jpg");
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "No-cache");
String captcha = CaptchaUtil.outputCaptchaImage(100, 30, os, CaptchaUtil.CAPTCHA_SIZE);
SessionUtil.getSession();
SessionUtil.setCaptcha(captcha);
os.flush();
} catch (IOException e) {
LOGGER.error("produce imageVerifyCode failed!");
LOGGER.error(e.getMessage(), e);
}
}
#3、前端页面调用方式
<div id="validatePanel" class="item" style="width: 137px;">
<input type="text" name="captcha" placeholder="请输入验证码" maxlength="4">
<img id="refreshCaptcha" class="validateImg" src="/common/generateCaptcha" >
</div>
打赏