首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java Web 實戰:從零手寫驗證碼功能(Servlet + Session)

     編輯:Java 綜合教學

Java Web 實戰:從零手寫驗證碼功能(Servlet + Session)

驗證碼可防暴力破解、刷票、灌水。本文演示基於 BufferedImage 生成圖片驗證碼,Session 存儲校驗碼,前端 JS 校驗非空。

項目結構

WebRoot/
├── index.jsp          # 頁面:輸入框、圖片、刷新、提交
├── servlet/
│   ├── ImageServlet   # 生成驗證碼圖片 + 存 Session
│   └── LoginServlet   # 校驗用戶輸入
└── web.xml (或 @WebServlet 註解)

核心代碼

1. index.jsp

<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>

2. ImageServlet.java

@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());
    }
}

3. LoginServlet.java

@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 等,支持點選、滑動、行為分析等更強防禦。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved