Java 图片验证码/图形验证码
1. Maven包 pom.xml
<!-- 父级 pom.xml-->
<properties>
<spring-boot.version>1.5.17.RELEASE</spring-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<!--Spring IO 控制依赖版本适配-->
<dependency>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Brussels-SR14</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--Spring Boot 控制依赖版本适配-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.22</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-config</artifactId>
<version>1.1.6.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子级 pom.xml-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-config</artifactId>
</dependency>
</dependencies>
2. 图片验证码工具类
import lombok.Data;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.time.LocalDateTime;
import java.util.Random;
@Data
public class ImageVerify {
@Data
public static class ImageCode {
private BufferedImage image;
private String code;
private LocalDateTime expireTime;
public ImageCode(final BufferedImage image, final String code, final int expireIn) {
this.image = image;
this.code = code;
this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
}
public boolean isExpire() {
return LocalDateTime.now().isAfter(expireTime);
}
}
private int width = 100; // 验证码图片宽度
private int height = 36; // 验证码图片长度
private int length = 4; // 验证码位数
private int fontSize = 32; // 验证码字体大小
private int letterSpace = fontSize / 2; // 字母间隔
private int lineSize = 200; // 干扰线数量
private int expireIn = 60; // 验证码有效时间 60s
private int positionX = 18; // x轴距
private int positionY = 28; // y轴距
public ImageVerify() {}
public ImageVerify(final int expireIn) {
this.expireIn = expireIn;
}
public ImageVerify(final int width, final int height, final int length, final int fontSize, final int expireIn, final int positionX, final int positionY) {
this.width = width;
this.height = height;
this.length = length;
this.fontSize = fontSize;
this.expireIn = expireIn;
this.positionX = positionX;
this.positionY = positionY;
}
public ImageCode create() {
final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
final Graphics graphics = image.getGraphics();
graphics.setColor(getRandColor(200, 500));
graphics.fillRect(0, 0, width, height);
graphics.setFont(new Font("Times New Roman", Font.ITALIC, fontSize));
graphics.setColor(getRandColor(100, 200));
final Random random = new Random();
/** 画干扰线*/
for (int i = 0; i < lineSize; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
graphics.drawLine(x, y, x + xl, y + yl);
}
/** 画验证码*/
final StringBuilder sRand = new StringBuilder();
for (int i = 0; i < length; i++) {
final String rand = String.valueOf(random.nextInt(10));
sRand.append(rand);
graphics.setColor(
new Color(
20 + random.nextInt(110),
20 + random.nextInt(110),
20 + random.nextInt(110)
)
);
graphics.drawString(rand, letterSpace * i + positionX, positionY);
}
graphics.dispose();
return new ImageCode(image, sRand.toString(), expireIn);
}
private Color getRandColor(int fc, int bc) {
final Random random = new Random();
if (fc > 255) fc = 255;
if (bc > 255) bc = 255;
final int r = fc + random.nextInt(bc - fc);
final int g = fc + random.nextInt(bc - fc);
final int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
}
3. 生成验证码,图片验证码 和 验证接口
import lombok.Data;
@Data
public class TestVo {
private String code;
}
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
public class ImageVerifyController {
/**
* Session Key
* */
public final static String SESSION_KEY_IMAGE_CODE = "SESSION_KEY_IMAGE_CODE";
private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
/**
* 生成图片验证码接口
*/
@GetMapping("/imageVerify")
public void imageVerify(HttpServletRequest request, HttpServletResponse response) throws IOException {
final ImageVerify.ImageCode imageCode = new ImageVerify(
68,/** 验证码图片宽度*/
36,/** 验证码图片长度*/
4,/** 验证码位数*/
32,/** 验证码字体大小*/
60,/** 验证码有效时间(秒)*/
2,/** x轴距*/
28/** y轴距*/
).create();
sessionStrategy.setAttribute(
new ServletWebRequest(request),
SESSION_KEY_IMAGE_CODE,
imageCode
);
ImageIO.write(imageCode.getImage(), "jpeg", response.getOutputStream());
response.getOutputStream().flush();
}
/**
* 验证接口
*/
@PostMapping("/verify")
public Map<String, String> verify(TestVo testVo, ServletWebRequest servletWebRequest) {
final ImageVerify.ImageCode imageCode = (ImageVerify.ImageCode) sessionStrategy.getAttribute(servletWebRequest, SESSION_KEY_IMAGE_CODE);
Map<String, String> m = new HashMap<>();
if (StringUtils.isBlank(testVo.getCode())) {
m.put("message", "验证码不能为空!");
return m;
}
if (imageCode == null) {
m.put("message", "验证码不存在!");
return m;
}
if (imageCode.isExpire()) {
sessionStrategy.removeAttribute(servletWebRequest, SESSION_KEY_IMAGE_CODE);
m.put("message", "验证码已过期!");
return m;
}
if (!StringUtils.equalsIgnoreCase(imageCode.getCode(), testVo.getCode())) {
m.put("message", "验证码不正确!");
return m;
}
sessionStrategy.removeAttribute(servletWebRequest, SESSION_KEY_IMAGE_CODE);
m.put("message", "成功");
return m;
}
/**
* 验证页面
*/
@GetMapping("/index")
public String index() {
return "index";
}
}
- 生成图片验证码
4. 验证页面 index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
<h2>Hello World!</h2>
<span>
<input type="text" id="textCode" placeholder="验证码" style="width: 50px" maxlength="4"/>
<img id="imageCode" src="/imageVerify" onclick="$(this).prop('src', '/imageVerify?' + Math.random())"/>
<input type="button" value="确认" onclick="verify()"/>
</span>
<script>
function verify() {
$.ajax({
async: false,
type: 'post',
url: '/verify',
dataType: "json",
data: {
code: $('#textCode').val()
},
success: function (result) {
if (result) {
console.log(result.message);
} else {
alert("failed!");
}
$("#imageCode").prop("src", '/imageVerify?' + Math.random());
}
});
}
</script>
</body>
</html>
如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!