自定义验证码 - kaptcha
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
package org.example.captcha;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* @author banjuan
* @date 2021/11/30 2:48 下午
*/
public class CodeUtil {
/**
* 将获取到的前端参数转为string类型
* @param request
* @param key
* @return
*/
public static String getString(HttpServletRequest request, String key) {
try {
String result = request.getParameter(key);
if(result != null) {
result = result.trim();
}
if("".equals(result)) {
result = null;
}
return result;
}catch(Exception e) {
return null;
}
}
/**
* 验证码校验
* @param request
* @return
*/
public static boolean checkVerifyCode(HttpServletRequest request) {
//获取生成的验证码
String verifyCodeExpected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
//获取用户输入的验证码
String verifyCodeActual = CodeUtil.getString(request, "verifyCodeActual");
if (null != verifyCodeActual) {
verifyCodeActual = verifyCodeActual.toLowerCase();
}
if(verifyCodeActual == null ||!verifyCodeActual.equals(verifyCodeExpected)) {
return false;
}
return true;
}
/**
* 宽高可作为参数传入
*/
private static final int WIDTH = 110;
private static final int HEIGHT = 40;
/**
* 传入BufferedImage对象,并将生成好的验证码保存到BufferedImage中
* @param bufferedImage
* @return
*/
public static String drawRandomText(BufferedImage bufferedImage) {
Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
// 设置画笔颜色-验证码背景色
graphics.setColor(Color.WHITE);
// 填充背景
graphics.fillRect(0, 0, WIDTH, HEIGHT);
graphics.setFont(new Font("宋体,楷体,微软雅黑", Font.BOLD, 26));
// 数字和字母的组合
String baseNumLetter = "123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
StringBuilder builder = new StringBuilder();
// 旋转原点的 x 坐标
int x = 8;
String ch;
Random random = new Random();
for (int i = 0; i < 4; i++) {
graphics.setColor(getRandomColor());
//设置字体旋转角度,角度小于30度
int degree = random.nextInt() % 30;
int dot = random.nextInt(baseNumLetter.length());
ch = baseNumLetter.charAt(dot) + "";
builder.append(ch);
//正向旋转
graphics.rotate(degree * Math.PI / 180, x, 24);
graphics.drawString(ch, x, 24);
//反向旋转
graphics.rotate(-degree * Math.PI / 180, x, 24);
x += 24;
}
//画干扰线
for (int i = 0; i < 6; i++) {
// 设置随机颜色
graphics.setColor(getRandomColor());
// 随机画线
graphics.drawLine(random.nextInt(WIDTH), random.nextInt(HEIGHT),
random.nextInt(WIDTH), random.nextInt(HEIGHT));
}
//添加噪点
for (int i = 0; i < 30; i++) {
int x1 = random.nextInt(WIDTH);
int y1 = random.nextInt(HEIGHT);
graphics.setColor(getRandomColor());
graphics.fillRect(x1, y1, 2, 2);
}
return builder.toString();
}
/**
* 随机取色
*/
private static Color getRandomColor() {
Random ran = new Random();
return new Color(ran.nextInt(256),
ran.nextInt(256), ran.nextInt(256));
}
}
package org.example.captcha;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
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;
/**
* @author banjuan
* @date 2021/11/30 2:45 下午
*/
@Controller
public class CodeController {
@Autowired
private Producer captchaProducer = null;
@RequestMapping("/kaptcha")
public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpSession session = request.getSession();
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
response.setContentType("image/jpeg");
//生成验证码
String capText = captchaProducer.createText();
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
//向客户端写出
BufferedImage bi = captchaProducer.createImage(capText);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(bi, "jpg", out);
try {
out.flush();
} finally {
out.close();
}
}
@RequestMapping("/verification")
public void createImageCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();
//禁止缓存
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.addHeader("Cache-Control", "post-check=0, pre-check=0");
response.setHeader("Pragma", "no-cache");
//设置响应格式为png图片
response.setContentType("image/png");
// 生成图片验证码
BufferedImage image = new BufferedImage(110, 40, BufferedImage.TYPE_INT_RGB);
String randomText = CodeUtil.drawRandomText(image);
session.setAttribute(Constants.KAPTCHA_SESSION_KEY, randomText.toLowerCase());
System.out.println("验证码->>>"+randomText);
ServletOutputStream out = response.getOutputStream();
ImageIO.write(image, "png", out);
out.flush();
out.close();
}
@RequestMapping("/hellow")
public String Hello() {
return "hello";
}
}
package org.example.captcha;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* @author banjuan
* @date 2021/11/30 2:59 下午
*/
@RestController
public class HelloWorld {
@RequestMapping("/hello")
public String hello(HttpServletRequest request) {
if (!CodeUtil.checkVerifyCode(request)) {
return "验证码有误!";
} else {
return "hello,world";
}
}
}
package org.example.captcha;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* @author banjuan
* @date 2021/11/30 3:01 下午
*/
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha getDefaultKaptcha(){
// DefaultKaptcha captchaProducer = new DefaultKaptcha();
// Properties properties = new Properties();
// properties.setProperty("kaptcha.border", "no");
// //properties.setProperty("kaptcha.border.color", "105,179,90");
// properties.setProperty("kaptcha.textproducer.font.color", "black");
// properties.setProperty("kaptcha.image.width", "110");
// properties.setProperty("kaptcha.image.height", "40");
// properties.setProperty("kaptcha.textproducer.font.size", "24");
// properties.setProperty("kaptcha.session.key", "code");
// properties.setProperty("kaptcha.noise.color", "white");
// properties.setProperty("kaptcha.textproducer.char.space", "4");
// properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.FishEyeGimpy");
//// properties.setProperty("kaptcha.background.clear.from", "0,255,0");
//// properties.setProperty("kaptcha.background.clear.to", "255,255,0");
// properties.setProperty("kaptcha.textproducer.char.length", "4");
//// properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
// properties.setProperty("kaptcha.textproducer.font.names", "Algerian");
// Config config = new Config(properties);
// captchaProducer.setConfig(config);
// return captchaProducer;
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
Properties properties = new Properties();
// 图片边框
properties.setProperty("kaptcha.border", "no");
// 边框颜色
//properties.setProperty("kaptcha.border.color", "105,179,90");
// 字体颜色
properties.setProperty("kaptcha.textproducer.font.color", "red");
// 验证码整体宽度
properties.setProperty("kaptcha.image.width", "110");
// 验证码整体高度
properties.setProperty("kaptcha.image.height", "40");
// 文字个数
properties.setProperty("kaptcha.textproducer.char.length", "4");
// 文字大小
properties.setProperty("kaptcha.textproducer.font.size","24");
// 文字随机字体
properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
// 文字距离
properties.setProperty("kaptcha.textproducer.char.space","4");
// 干扰线颜色
properties.setProperty("kaptcha.noise.color","blue");
// 自定义验证码背景
//properties.setProperty("kaptcha.background.impl","com.dt.springbootdemo.config.kaptcha.NoKaptchaBackhround");
Config config=new Config(properties);
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
function refresh() {
document.getElementById('captcha_img').src="/verification?"+Math.random();
}
</script>
</head>
<body>
<form action="/hello" method="post">
验证码: <input type="text" placeholder="请输入验证码" name="verifyCodeActual">
<div class="item-input">
<img id="captcha_img" alt="点击更换" title="点击更换"
onclick="refresh()" src="/verification" />
</div>
<input type="submit" value="提交" />
</form>
</body>
</html>


浙公网安备 33010602011771号