|
|
|
|
@ -9,33 +9,77 @@ import java.io.IOException;
|
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 验证码生成工具类
|
|
|
|
|
* 用于生成图形验证码,支撑用户登录时的安全校验,防止恶意登录或自动化脚本攻击
|
|
|
|
|
*/
|
|
|
|
|
public class ImageCode {
|
|
|
|
|
public static final String CODENAME="ImageCode";
|
|
|
|
|
// 验证码在HttpSession中的存储键名(固定值,登录时需通过该键名获取Session中的验证码)
|
|
|
|
|
public static final String CODENAME = "ImageCode";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成图形验证码并响应给前端,同时将验证码存入Session
|
|
|
|
|
* @param response HttpServletResponse,用于向前端输出验证码图片
|
|
|
|
|
* @param session HttpSession,用于存储生成的验证码(供登录时校验)
|
|
|
|
|
* @throws IOException 图片写入响应流时可能抛出IO异常,需调用方处理
|
|
|
|
|
*/
|
|
|
|
|
public static void createImage(HttpServletResponse response, HttpSession session) throws IOException {
|
|
|
|
|
// 1. 创建 BufferedImage 对象(验证码图片载体):宽80px、高30px,RGB色彩模式
|
|
|
|
|
BufferedImage image = new BufferedImage(80, 30, BufferedImage.TYPE_INT_RGB);
|
|
|
|
|
|
|
|
|
|
// 2. 获取 Graphics 对象(用于在图片上绘制内容:背景、验证码文字、干扰元素等)
|
|
|
|
|
Graphics g = image.getGraphics();
|
|
|
|
|
|
|
|
|
|
// 3. 创建随机数对象(用于生成随机颜色、干扰元素位置等,增强验证码安全性)
|
|
|
|
|
Random r = new Random();
|
|
|
|
|
|
|
|
|
|
// 4. 绘制验证码背景:随机颜色填充矩形(覆盖整个图片区域,宽80px、高20px)
|
|
|
|
|
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
|
|
|
|
|
g.fillRect(0, 0, 80, 20);
|
|
|
|
|
//获取生成的验证码
|
|
|
|
|
|
|
|
|
|
// 5. 生成4位随机验证码(数字+大写字母组合)
|
|
|
|
|
String code = getNumber();
|
|
|
|
|
//绑定验证码
|
|
|
|
|
|
|
|
|
|
// 6. 将生成的验证码存入Session:键为CODENAME,值为验证码,供后续登录校验使用
|
|
|
|
|
session.setAttribute(CODENAME, code);
|
|
|
|
|
|
|
|
|
|
// 7. 设置验证码文字样式:无衬线字体、加粗、字号25px
|
|
|
|
|
g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 25));
|
|
|
|
|
|
|
|
|
|
// 8. 设置验证码文字颜色:随机RGB颜色(与背景色区分,确保清晰可见)
|
|
|
|
|
g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
|
|
|
|
|
|
|
|
|
|
// 9. 绘制验证码文字到图片:起始位置(x=5px,y=25px),避免文字超出图片边界
|
|
|
|
|
g.drawString(code, 5, 25);
|
|
|
|
|
//设置消息头
|
|
|
|
|
|
|
|
|
|
// 10. 设置响应头:指定返回内容类型为image/jpeg(告诉前端这是图片数据)
|
|
|
|
|
response.setContentType("image/jpeg");
|
|
|
|
|
|
|
|
|
|
// 11. 获取响应输出流,将验证码图片以jpeg格式写入流,响应给前端
|
|
|
|
|
OutputStream os = response.getOutputStream();
|
|
|
|
|
ImageIO.write(image, "jpeg", os);
|
|
|
|
|
}
|
|
|
|
|
public static String getNumber(){
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 生成4位随机验证码(包含数字0-9和大写字母A-Z,增强验证码复杂度)
|
|
|
|
|
* @return 4位随机字符串(验证码内容)
|
|
|
|
|
*/
|
|
|
|
|
public static String getNumber() {
|
|
|
|
|
// 1. 定义验证码字符池:包含数字和大写字母,共36个字符
|
|
|
|
|
String str = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
|
|
|
|
|
|
|
|
// 2. 初始化验证码字符串(用于拼接最终结果)
|
|
|
|
|
String code = "";
|
|
|
|
|
for(int i= 0;i<4;i++){
|
|
|
|
|
int index = (int)(Math.random()*str.length());
|
|
|
|
|
code+=str.charAt(index);
|
|
|
|
|
|
|
|
|
|
// 3. 循环4次,每次从字符池中随机选取1个字符,组成4位验证码
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
// 生成0到str长度-1的随机索引(确保不越界)
|
|
|
|
|
int index = (int) (Math.random() * str.length());
|
|
|
|
|
// 根据索引获取字符,拼接到验证码中
|
|
|
|
|
code += str.charAt(index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4. 返回生成的4位验证码
|
|
|
|
|
return code;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|