验证码
引入依赖
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
编码实现
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.util.RandomUtil;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.concurrent.ThreadLocalRandom;
public class SimpleCaptcha extends LineCaptcha{
private static final long serialVersionUID = -9042552338521307038L;
private static final String CAPTCHA_CODE = "abcdefhjkmnpqrstuvwxyz2345678";
private final int codeCount;
public SimpleCaptcha(int width, int height, int codeCount, int interfereCount) {
super(width, height, codeCount, interfereCount);
this.codeCount = codeCount;
}
@Override
protected void generateCode() {
this.code = RandomUtil.randomString(CAPTCHA_CODE,codeCount);
}
@Override
public Image createImage(String code) {
// 图像buffer
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
final ThreadLocalRandom random = RandomUtil.getRandom();
final Graphics2D g = ImgUtil.createGraphics(image, new Color(249,249,249));
// 干扰线
drawInterfere(g, random);
// 创建字体
g.setFont(this.font);
final FontMetrics metrics = g.getFontMetrics();
int minY = metrics.getAscent() - metrics.getLeading() - metrics.getDescent();
// 文字
final int len = codeCount;
int charWidth = width / len;
for (int i = 0; i < len; i++) {
// 产生随机的颜色值,让输出的每个字符的颜色值都将不同。
g.setColor(ImgUtil.randomColor(random));
g.setFont(new Font("Arial", Font.PLAIN, random.nextInt(20)+30));
g.drawString(String.valueOf(code.charAt(i)), i * charWidth, RandomUtil.randomInt(minY, this.height));
}
return image;
}
/**
* 绘制干扰线
*
* @param g {@link Graphics2D}画笔
* @param random 随机对象
*/
private void drawInterfere(Graphics2D g, ThreadLocalRandom random) {
// 干扰线
for (int i = 0; i < this.interfereCount; i++) {
int xs = random.nextInt(width);
int ys = random.nextInt(height);
int xe = xs + random.nextInt(width / (random.nextInt(8)+1));
int ye = ys + random.nextInt(height / (random.nextInt(8)+1));
g.setColor(ImgUtil.randomColor(random));
g.drawLine(xs, ys, xe, ye);
}
}
public static void main(String[] args) {
SimpleCaptcha simpleCaptcha = new SimpleCaptcha(104, 50, 4, 50);
simpleCaptcha.write("D:\\work\\123.jpg");
}
}
控制器访问
@GetMapping("/captcha.jpg")
public Object login(HttpServletRequest request,@RequestParam(required = false, defaultValue = "false") String value
,@RequestParam(required = false, defaultValue = "104") int width,@RequestParam(required = false, defaultValue = "50") int height) {
//定义图形验证码的长、宽、验证码字符数、干扰元素个数
SimpleCaptcha simpleCaptcha = new SimpleCaptcha(width, height, 4, 30);
if (value.equals("true")) {
ConcurrentHashMapCacheUtils.setCache("captcha_jpg" + request.getRemoteAddr(), simpleCaptcha.getCode(), 1000*60*5);
return ResponseUtil.ok(simpleCaptcha.getCode());
}
try(ByteArrayOutputStream stream = new ByteArrayOutputStream()) {
simpleCaptcha.write(stream);
String base64 = Base64.encode(stream.toByteArray());
ConcurrentHashMapCacheUtils.setCache("captcha_jpg" + request.getRemoteAddr(), simpleCaptcha.getCode(), 1000*60*5);
return ResponseUtil.ok(base64);
} catch (IOException e) {
e.printStackTrace();
}
return ResponseUtil.fail();
}