前言
很多新手對(duì)圖片驗(yàn)證碼不是很了解,所以本文嘗試通過(guò)一個(gè)簡(jiǎn)單的 JSP 小程序來(lái)實(shí)現(xiàn)驗(yàn)證碼功能。文中給出了詳細(xì)的示例代碼,文末給出了完整實(shí)例代碼的下載地址,下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
效果圖
示例代碼
前臺(tái)代碼如下:
form action="action.jsp" method="POST">
label> 用戶名:
input type="text" name="name" data-singleTips="請(qǐng)輸入用戶名" value="admin" />
/label>
label> 密碼: input type="password" name="password" />
/label>
!-- 驗(yàn)證碼 -->
label class="captchaCode">
驗(yàn)證碼: img src="img.jsp" style="cursor: pointer;" onclick="this.src=this.src + '?' + new Date().valueOf();" />
input type="text" name="captchaImgCode" />
/label>
div>
input type="submit" value="登錄" />
/div>
/form>
驗(yàn)證碼圖片從何而來(lái)? img.jsp 是也:
%@include file="captcha.jsp"%>
%
init(pageContext);// 加載圖片
%>
返回圖片的數(shù)據(jù)流。
action.jsp 這里不作用戶名或密碼的檢驗(yàn),只是單純驗(yàn)證碼檢驗(yàn)。
如果輸入驗(yàn)證碼通過(guò),顯示如下:
反之,給出已捕獲的異常:
action.jsp 就是調(diào)用 captcha.jsp 里面的 isPass(pageContext, captchaImgCode)
方法,以及捕獲已知異常。
%@page pageEncoding="UTF-8"%>
%@include file="captcha.jsp"%>
%
String captchaImgCode = request.getParameter("captchaImgCode");
try {
if (isPass(pageContext, captchaImgCode)) {
out.println("驗(yàn)證碼通過(guò)!");
}
} catch (Throwable e) {
out.println(e);
}
%>
核心 captcha,jsp 代碼:
%@page pageEncoding="UTF-8" import="java.io.IOException, java.awt.*, java.awt.image.BufferedImage, java.util.Random, javax.imageio.ImageIO"%>
%!
// 定義Captcha 類(lèi)
public static class Captcha {
/**
* 默認(rèn)寬度 60
*/
private int width = 60;
/**
* 默認(rèn)高度 20
*/
private int height = 20;
/**
* 驗(yàn)證碼
*/
private String code;
/**
* 生成驗(yàn)證碼圖片
*
* @return 圖片對(duì)象
*/
public BufferedImage get() {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 在內(nèi)存中創(chuàng)建圖像
Graphics g;
g = image.getGraphics(); // 獲取圖形上下文
g.setColor(getRandColor(200, 250)); // 設(shè)定背景
g.fillRect(0, 0, width, height);
g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); // 設(shè)定字體
g.setColor(getRandColor(160, 200));
Random random = new Random();// 隨機(jī)產(chǎn)生干擾線
for (int i = 0; i 155; i++) {
int x = random.nextInt(width), y = random.nextInt(height);
int xl = random.nextInt(12), yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
String sRand = ""; // 隨機(jī)產(chǎn)生4位驗(yàn)證碼
for (int i = 0; i 4; i++) {
String rand = String.valueOf(random.nextInt(10));
sRand += rand;
g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); // 將認(rèn)證碼顯示到圖象中
g.drawString(rand, 13 * i + 6, 16);// 調(diào)用函數(shù)出來(lái)的顏色相同,可能是因?yàn)榉N子太接近,所以只能直接生成
}
// 將認(rèn)證碼存入SESSION
// session.setAttribute("rand", sRand);
setCode(sRand);
g.dispose();// 圖象生效
return image;
}
/**
* 生成隨機(jī)顏色
*
* @param fc
* @param bc
* @return
*/
private Color getRandColor(int fc, int bc) {
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
Random random = new Random();
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
/**
* 獲取高度
*
* @return
*/
public int getHeight() {
return height;
}
/**
* 設(shè)置高度
*
* @param height
* 高度
*/
public void setHeight(int height) {
this.height = height;
}
/**
* 獲取驗(yàn)證碼
*
* @return
*/
public String getCode() {
return code;
}
/**
* 設(shè)置驗(yàn)證碼
*
* @param code
* 驗(yàn)證碼
*/
public void setCode(String code) {
this.code = code;
}
/**
* 獲取寬度
*
* @return
*/
public int getWidth() {
return width;
}
/**
* 設(shè)置寬度
*
* @param width
* 寬度
*/
public void setWidth(int width) {
this.width = width;
}
}
/**
* SESSION 的鍵值
*/
public static final String SESSION_KEY = "rand";
/**
* 顯示驗(yàn)證碼圖片并將認(rèn)證碼存入 Session
*
* @param response
* 響應(yīng)對(duì)象
* @param session
* 會(huì)話對(duì)象
*/
public static void init(HttpServletResponse response, HttpSession session) {
Captcha img = new Captcha();
// 不用緩存
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpg");
try {
ImageIO.write(img.get(), "JPEG", response.getOutputStream());
/*
* 加上下面代碼,運(yùn)行時(shí)才不會(huì)出現(xiàn)java.lang.IllegalStateException: getOutputStream() has already been called ..........等異常
* response.getOutputStream().flush();
* response.getOutputStream().close();
* response.flushBuffer();
*/
// JSP內(nèi)置對(duì)象out和response.getWrite()的區(qū)別,兩者的主要區(qū)別:1. 這兩個(gè)對(duì)象的類(lèi)型是完全不同的……
// response.getWriter();
// http://blog.sina.com.cn/s/blog_7217e4320101l8gq.html
// https://www.jb51.net/kf/201109/103284.html
// pageContext.getOut().clear();
} catch (IOException e) {
e.printStackTrace();
}
session.setAttribute(SESSION_KEY, img.getCode()); // 將認(rèn)證碼存入 SESSION
System.out.println("生成驗(yàn)證碼:" + img.getCode());
}
/**
* 顯示驗(yàn)證碼圖片并將認(rèn)證碼存入 Session(For JSP)
*
* @param pageContext
* 頁(yè)面上下文對(duì)象
*/
public static void init(PageContext pageContext) {
init((HttpServletResponse) pageContext.getResponse(), pageContext.getSession());
}
/**
* 判斷用戶輸入的驗(yàn)證碼是否通過(guò)
*
* @param pageContext
* 頁(yè)面上下文對(duì)象
* @return true 表示通過(guò)
* @throws Throwable
*/
public static boolean isPass(PageContext pageContext, String code) throws Throwable {
boolean isCaptchaPass = false;
String rand = (String) pageContext.getSession().getAttribute(SESSION_KEY);
System.out.println("rand:" + rand);
System.out.println("CaptchaCode:" + code);
if (rand == null)
throw new UnsupportedOperationException("請(qǐng)刷新驗(yàn)證碼。");
else if (code == null || code.equals("")) {
throw new IllegalArgumentException("沒(méi)提供驗(yàn)證碼參數(shù)");
} else {
isCaptchaPass = rand.equals(code);
if (!isCaptchaPass)
throw new IllegalAccessError("驗(yàn)證碼不正確");
}
return isCaptchaPass;
}
%>
完整代碼下載:http://xiazai.jb51.net/201707/yuanma/Captcha(jb51.net).rar
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
您可能感興趣的文章:- JSP開(kāi)發(fā)之生成圖片驗(yàn)證碼技術(shù)的詳解