基於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(...){
	     	....
	     }
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章