驗證碼可防暴力破解、刷票、灌水。本文演示基於 BufferedImage 生成圖片驗證碼,Session 存儲校驗碼,前端 JS 校驗非空。
WebRoot/ ├── index.jsp # 頁面:輸入框、圖片、刷新、提交 ├── servlet/ │ ├── ImageServlet # 生成驗證碼圖片 + 存 Session │ └── LoginServlet # 校驗用戶輸入 └── web.xml (或 @WebServlet 註解)
<form action="servlet/LoginServlet" method="get" onsubmit="return doIt();">
驗證碼:<input type="text" name="codeCheck" id="code">
<img id="image" src="<%=request.getContextPath()%>/servlet/ImageServlet" />
<a href="javascript:reload();">看不清</a><br>
<input type="submit" value="submit">
</form>
<script>
function reload() {
document.getElementById("image").src = "<%=request.getContextPath()%>/servlet/ImageServlet?id=" + new Date().getTime();
}
function doIt() {
var code = document.getElementById("code").value;
if (!code) { alert("驗證碼不能為空!"); return false; }
return true;
}
</script>
@WebServlet("/servlet/ImageServlet")
public class ImageServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
BufferedImage img = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);
Graphics g = img.getGraphics();
g.setColor(new Color(225, 230, 246));
g.fillRect(0, 0, 68, 22);
char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();
Random r = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++) {
char c = chars[r.nextInt(chars.length)];
g.setColor(new Color(r.nextInt(88), r.nextInt(188), r.nextInt(255)));
g.drawString(String.valueOf(c), i * 15 + 3, 18);
sb.append(c);
}
req.getSession().setAttribute("code", sb.toString());
ImageIO.write(img, "JPG", resp.getOutputStream());
}
}
@WebServlet("/servlet/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String input = req.getParameter("codeCheck");
String real = (String) req.getSession().getAttribute("code");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println(input.equalsIgnoreCase(real) ? "驗證碼成功!" : "驗證碼失敗!");
out.close();
}
}
手寫驗證碼易被識別,生產環境建議使用成熟庫:kaptcha、jcaptcha、Google reCAPTCHA 等,支持點選、滑動、行為分析等更強防禦。