基於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(...){
....
}
}