流程:验证码图片由服务器的java后端生成,前端向后端请求图片验证码,项目工程使用了springboot框架
生成图片验证码的工具类:
package com.main.activity.verifyCode;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
public class ImageUtil {
public ImageUtil() {
}
public static OutputStream generator(int width, int height, String checkCode) {
BufferedImage image = new BufferedImage(width, height, 5);
Graphics g = image.getGraphics();
Random random = new Random();
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
g.setColor(getRandColor(0, 255));
g.drawRect(0, 0, width - 1, height - 1);
g.setColor(getRandColor(160, 200));
int i;
int y;
for (i = 0; i < 8; ++i) {
i = random.nextInt(width);
y = random.nextInt(height);
int x1 = random.nextInt(width);
int y1 = random.nextInt(height);
g.drawLine(i, y, x1, y1);
}
g.setColor(getRandColor(160, 200));
for (i = 0; i < 100; ++i) {
i = random.nextInt(width);
y = random.nextInt(height);
g.drawLine(i, y, i, y);
}
Font font = new Font("Arial Black", 2, 25);
g.setFont(font);
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
for (i = 0; i < checkCode.length(); ++i) {
g.drawString(String.valueOf(checkCode.charAt(i)), 22 * i + 2, 20);
}
g.dispose();
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(image, "jpeg", os);
} catch (IOException var11) {
var11.printStackTrace();
}
return os;
}
private static Color getRandColor(int lower, int upper) {
Random random = new Random();
if (upper > 255) {
upper = 255;
}
if (upper < 1) {
upper = 1;
}
if (lower < 1) {
lower = 1;
}
if (lower > 255) {
lower = 255;
}
int r = lower + random.nextInt(upper - lower);
int g = lower + random.nextInt(upper - lower);
int b = lower + random.nextInt(upper - lower);
return new Color(r, g, b);
}
}
请求验证码图片以及验证码值的controller:
package com.main.activity.verifyCode;
import com.main.dao.DataBaseOP;
import net.sf.json.JSONArray;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.UUID;
@RestController
public class VerifyCodeController {
/**
* 去除 l、o、I、O、0、1
*/
private static final char[] CHAR_ARRAY = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789".toCharArray();
/**登录图片验证码
* @param session
* @return
*/
@GetMapping("/getVerifyImage")
public void getVerifyImage(HttpServletRequest request, HttpServletResponse res, HttpSession session) throws IOException {
String checkCode = RandomStringUtils.random(4, CHAR_ARRAY);
//TODO 直接返回byte数据
ByteArrayOutputStream os = (ByteArrayOutputStream) ImageUtil.generator(102, 25, checkCode);
byte[] bytes = os.toByteArray();
try {
os.close();
} catch (IOException e) {
}
session.setAttribute("checkCode", checkCode);//将验证码值存入HttpSession中
res.setContentType("image/jpg");
res.setContentLength(bytes.length);
res.getOutputStream().write(bytes);
}
@GetMapping("/getCheckCode")//该方法为验证码值的获取方法
public Object getCheckCode(HttpSession session) {
return session.getAttribute("checkCode");
}
}
前端界面(我的端口号为8099)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
var checkCode="";
function reCheckcode() {
$("#image").attr({"src":"http://localhost:8099/getVerifyImage?w="+Math.random()});
document.getElementById("image").onload=function (ev) {
getCheckCode();
}
}
function getCheckCode(){
$.get("http://localhost:8099/getCheckCode",function (data) {
checkCode=data;
console.info(checkCode);
return checkCode;
})
}
window.onload=function (ev) {
reCheckcode();
}
</script>
</head>
<body>
<img id="image" style="height:100%;" title="点击更换验证码" onclick="reCheckcode()" />
</body>
</html>
在获取验证码值时遇到一个bug:
关于图片验证码刷新问题,要获得新的图片验证码的字符串值,但总是会
出现问题,获得的验证码是上一次的验证码,不是新的验证码,查找错误后
发现原因是向后台请求验证码图片并且前台加载验证码都需要一定的时间,
而我的向后台获取验证码值的执行速度较快,所以导致获得的验证码值总是上一次
的验证码值。
解决方法:
1.使用setTimeout方法,在刷新验证码后的500ms再执行该获得验证码值的方法
eg:setTimeout(getCheckCode,500);
2.使用html元素image的onload方法,即当图片加载完成后再进行获取验证码的操作,
eg:document.getElementById("image").οnlοad=function (ev) {
getCheckCode();
};
(其中getCheckCode()是获得验证码值的方法)
参考博客:
https://blog.csdn.net/jiahao1186/article/details/82501009