生成登入時的圖片驗證碼
阿新 • • 發佈:2018-11-23
環境:springboot專案
思路:從後臺生成圖片,然後傳輸到前臺顯示,每次生成的驗證碼儲存在session裡
借鑑了別人用java生成圖片的方法
直接上程式碼
前端剛載入登入頁面時和每次點選圖片獲取驗證碼的url介面
/**生成圖片驗證碼*/
@RequestMapping("verifyCode/ImageCode")
@ResponseBody
public JSONObject produceImageCode(HttpSession session) throws IOException {
JSONObject jobj = new JSONObject();
ImageUtil iu = new ImageUtil();
String code = iu.createImageWithVerifyCode(120,30,4,session);
code = "data:image/png;base64,"+code;
jobj.put("png_base64",code);
return jobj;
}
使用到的ImageUtil類的函式,用於生成帶驗證碼的圖片
/**生成驗證碼圖片 轉 base64 並且儲存圖片驗證碼到session裡
* @param width 圖片寬度
* @param height 圖片高度
* @param session session域 用來儲存驗證碼
* @param length 驗證碼位數
* @return 圖片的base64串*/
public String createImageWithVerifyCode(int width, int height, int length,HttpSession session) throws IOException {
String png_base64="";
//繪製記憶體中的圖片
BufferedImage bufferedImage = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//得到畫圖物件
Graphics graphics = bufferedImage.getGraphics();
//繪製圖片前指定一個顏色
graphics.setColor(getRandColor(160,200));
graphics.fillRect(0,0,width,height);
//繪製邊框
graphics.setColor(Color.white);
graphics.drawRect(0, 0, width - 1, height - 1);
// 步驟四 四個隨機數字
Graphics2D graphics2d = (Graphics2D) graphics;
graphics2d.setFont(new Font("宋體", Font.BOLD, 18));
Random random = new Random();
VerifyCodeUtil vcu = new VerifyCodeUtil();
String word = vcu.produceNumAndChar(length);
// 定義x座標
int x = 10;
for (int i = 0; i < word.length(); i++) {
// 隨機顏色
graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
// 旋轉 -30 --- 30度
int jiaodu = random.nextInt(60) - 30;
// 換算弧度
double theta = jiaodu * Math.PI / 180;
// 獲得字母數字
char c = word.charAt(i);
//將c 輸出到圖片
graphics2d.rotate(theta, x, 20);
graphics2d.drawString(String.valueOf(c), x, 20);
graphics2d.rotate(-theta, x, 20);
x += 30;
}
//儲存驗證碼
session.setAttribute("img_code",word);
// 繪製干擾線
graphics.setColor(getRandColor(160, 200));
int x1;
int x2;
int y1;
int y2;
for (int i = 0; i < 30; i++) {
x1 = random.nextInt(width);
x2 = random.nextInt(12);
y1 = random.nextInt(height);
y2 = random.nextInt(12);
graphics.drawLine(x1, y1, x1 + x2, x2 + y2);
}
graphics.dispose();// 釋放資源
ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
ImageIO.write(bufferedImage, "png", baos);//寫入流中
byte[] bytes = baos.toByteArray();//轉換成位元組
BASE64Encoder encoder = new BASE64Encoder();
png_base64 = encoder.encodeBuffer(bytes).trim();
png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//刪除 \r\n
return png_base64;
}
生成隨機的N位數字和字母混合的驗證碼字串
這裡去掉了字母O和數字0 可以把字母和數字都定義在同一個字串內
/**生成N位數字和字母混合的驗證碼
* @param num 驗證碼位數
* @return code 生成的驗證碼字串*/
public String produceNumAndChar(int num){
Random random = new Random();
String code = "";
String ch = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
String n = "123456789";
for(int i=0;i<num;i++){
int flag = random.nextInt(2);
if(flag==0){//數字
code+=n.charAt(random.nextInt(n.length()));
}else{//字母
code+=ch.charAt(random.nextInt(ch.length()));
}
}
return code;
}
前端介面程式碼和Js程式碼
<div class="form-group" >
<input type="text" name="img_code" id="img_code" th:value="${img_code}" class="form-control" placeholder="驗證碼" style="color:gray;float:left;width:180px !important;height:30px !important;" required="required" />
<img id="img" style="float:left;margin-left:20px" onclick="javascript:imgChange()" />
</div>
$(function(){
imgChange();
});
function imgChange(){
$.ajax({
type: "POST",
dataType: "json",
url: "/verifyCode/ImageCode" ,
data:{},
success: function (result) {
$("#img").attr('src',result.png_base64)
},
error : function() {
alert("操作發生異常,請重新整理頁面後再試!");
}
});
}
注意
//在生成圖片的時候,驗證碼我是儲存在了Session裡的
//儲存驗證碼
session.setAttribute("img_code",word);
//在登入的時候進行驗證碼是否正確的判斷
if(!img_code.equalsIgnoreCase((String)session.getAttribute("img_code"))){
//.......
}
//取seesion裡的驗證碼的時候,最好捕獲下session的異常
//登入成功的話進行session的銷燬
try{
session.removeAttribute("img_code");
}catch(Exception e){
//.......
}