圖片驗證碼是 Web 應用中防止機器人惡意登入、註冊的常見手段。本文提供一個基於 JSP 的完整範例,包含前端登入頁面與後端動態生成驗證碼圖片的邏輯,適合初學者參考。
前端頁面包含帳號、密碼、驗證碼輸入框,並將驗證碼圖片綁定點擊刷新事件。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登入頁面</title>
<script type="text/javascript">
function refresh() {
loginForm.image.src = "creatImage.jsp";
}
</script>
</head>
<body>
<h1>歡迎登入本系統</h1>
<form action="" method="post" name="loginForm">
<label>帳號:<input name="username" type="text" /></label><br>
<label>密碼:<input name="password" type="password" /></label><br>
<label>驗證碼:<input name="code" type="text" /></label>
<!-- 將驗證碼當作圖片處理 -->
<img name="image" border="0" src="creatImage.jsp" onclick="refresh()" />
<input type="submit" value="登入" />
</form>
</body>
</html>
後端使用 BufferedImage 繪製隨機字元、干擾線,並將驗證碼存入 Session 供後續驗證。
<%@page import="java.util.Random"%>
<%@page import="java.awt.Graphics"%>
<%@page import="javax.imageio.*"%>
<%@page import="java.awt.*"%>
<%@page import="java.awt.image.BufferedImage"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
final char[] str = {'0','1','2','3','4','5','6','7','8','9',
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
int width = 100, height = 60;
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
g.setColor(new Color(200, 200, 200));
g.fillRect(0, 0, width, height);
Random rnd = new Random();
StringBuffer sb = new StringBuffer();
// 產生四位英數驗證碼,每個字元顏色隨機
for (int i = 0; i < 4; i++) {
int num = rnd.nextInt(str.length);
Color c = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
g.setColor(c);
g.setFont(new Font("", Font.BOLD + Font.ITALIC, 20));
g.drawString(str[num] + "", 10 + i * 20, 35);
sb.append(str[num]);
}
// 畫干擾線
for (int i = 0; i < 10; i++) {
Color c = new Color(rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
g.setColor(c);
g.drawLine(rnd.nextInt(width), rnd.nextInt(height), rnd.nextInt(width), rnd.nextInt(height));
}
String code = sb.toString();
// 存入 Session,供登入驗證比對
session.setAttribute("image", code);
// 輸出圖片
ImageIO.write(bi, "JPEG", response.getOutputStream());
out.clear();
out = pageContext.pushBody();
%>
session.setAttribute("image", code),登入時比對用戶輸入。ImageIO.write 直接寫入 response.getOutputStream(),避免 IllegalStateException。refresh(),重新請求 creatImage.jsp 產生新驗證碼。實際專案建議: