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

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

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

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中,专门供前端发送请求获取。这里的重点在于:如何将图片进行输出、以及避免图片的缓存而导致验证码更换的不及时。
	@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连接到接口,请求验证码图片。
<img th:src="@{/user/code}" />
input type="text" class="form-control" name="code"
      id="code" placeholder="验证码">

上面< img >标签中直接使用模板引擎的语法,动态获取图片。
在模板引擎中,@{/} 表示根路径,也就是部署在Web服务器容器上的项目名称。而之后的user/code则表示,去到user路径下的code路径。这也就相当于,我们在controller中对路径进行拦截,代码:

	@RequestMapping("/user")
	public class UserController{
	
	     @RequestMapping("/code")
	     public void code(...){
	     	....
	     }
	}
发布了11 篇原创文章 · 获赞 1 · 访问量 1860
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 1024 设计师: 上身试试

分享到微信朋友圈

×

扫一扫,手机浏览