基于java.awt 绘制 自定义图片算式验证码

一、创建绘制图片验证码的类

java 复制代码
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class VerifyCode {

	// 计算结果
	private int result;

	public BufferedImage createImage() {
		// 图片宽度
		int width = 105;
		// 图片高度
		int height = 32;

		// 创建BufferedImage对象
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics graphics = image.getGraphics();

		// 设置背景颜色
		graphics.setColor(new Color(0xCDDCDC));
		graphics.fillRect(0, 0, width, height);

		// 画边框
		graphics.setColor(Color.black);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 随机做干扰线
		Random random = new Random();
		for (int i = 0; i < 15; 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);
		}

		// 生成验证码表达式,如:1+2 / 2*3 / 4 - 2
		String verifyCode = this.generateExpression();
		
		// 开始画图
		graphics.setColor(new Color(0, 88, 0));
		graphics.setFont(new Font("Fixedsys", Font.BOLD, 24));
		graphics.drawString(verifyCode + " = ?", 8, 24);
		graphics.dispose();

		// 计算表达式结果
		result = this.calc(verifyCode);

		// 返回图片对象
		return image;
	}

	public int getResult() {
		return result;
	}

	/**
	 * 计算表达式的值
	 * 
	 * @param expression
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	private int calc(String expression) {
		try {
			ScriptEngineManager manager = new ScriptEngineManager();
			ScriptEngine engine = manager.getEngineByName("JavaScript");
			return (Integer) engine.eval(expression);
		} catch (Exception e) {
			return 0;
		}
	}

	/**
	 * 生成验证码表达式:1+2
	 * @return
	 * @see [类、类#方法、类#成员]
	 */
	private String generateExpression() {
		Random random = new Random();
		// 随机获取操作数 0-9
		int number = random.nextInt(10);
		int number2 = random.nextInt(10);
		//int number3 = random.nextInt(10);
		
		char[] operators = new char[] { '+', '-', '*' };

		// 随机拿出一个操作符 
		char operator1 = operators[random.nextInt(3)];// 0-2
		//char operator2 = operators[random.nextInt(3)];
		return "" + number +" "+ operator1 +" "+ number2 ;
	}

	public static void main(String[] args) {
		VerifyCode verifyCode = new VerifyCode();
		String exp = verifyCode.generateExpression();
		System.out.println(exp + "=" + verifyCode.calc(exp));
	}

运算算式生成部分,完全可以根据自己的需求来更改,注释中注释了3个数之间的加、减、乘运算,由于除运算结果比较复杂,可能有小数点的出现,所以不考虑在内。

二、创建一个接口,专门供给前端返回验证码图片

我们将这个Http接口定义在controller中,专门供前端发送请求获取。这里的重点在于:如何将图片进行输出、以及避免图片的缓存而导致验证码更换的不及时。

java 复制代码
	@RequestMapping("/code")
	public void code(HttpServletRequest request, 
		HttpServletResponse response) throws IOException {
		
		//创建验证码对象
		VerifyCode vc = new VerifyCode();
		
		//创建验证码图片 
		BufferedImage image = vc.createImage();
		
		//设置Http响应头  禁止图像缓存
		response.setHeader("Cache-Control","no-cache");
		response.setHeader("Pragma", "no-cache");
		response.setDateHeader("Expires", 0);	//响应具体的过期时间
		response.setContentType("image/jpeg");
		
		//获取表达式结果存入session
		request.getSession().setAttribute("vcode", vc.getResult());
		
		//将图片写回出到前端
		ImageIO.write(image, "JPEG", response.getOutputStream());
	}

三、接收图片

由于是在html中,我们可以使用thymleaf模板引擎,直接发送http连接到接口,请求验证码图片。

javascript 复制代码
<img th:src="@{/user/code}" />
input type="text" class="form-control" name="code"
      id="code" placeholder="验证码">

上面< img >标签中直接使用模板引擎的语法,动态获取图片。

在模板引擎中,@{/} 表示根路径,也就是部署在Web服务器容器上的项目名称。而之后的user/code则表示,去到user路径下的code路径。这也就相当于,我们在controller中对路径进行拦截,代码:

java 复制代码
	@RequestMapping("/user")
	public class UserController{
	
	     @RequestMapping("/code")
	     public void code(...){
	     	....
	     }
	}
相关推荐
步行cgn23 分钟前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川29 分钟前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵32 分钟前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
程序喵大人34 分钟前
【C++入门】内存模型与资源管理 - 09 shared_ptr 和 weak_ptr 解决共享,也带来代价
开发语言·c++·资源管理·智能指针·内存模型
quantdash_cc1 小时前
如何验证历史行情的交易日期是否完整覆盖研究区间?
python·数据分析·pandas·量化交易·股票数据·quantdash
I Am a robert girl1 小时前
当智能体学会“串通”:从长程交互中读懂涌现式合谋
python·多智能体系统·多智能体协作·llm agent·涌现式合谋·对齐问题·激励机制设计
秋天的怀念_David1 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1001 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
云和数据.ChenGuang2 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
niucloud-admin2 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php