代碼邏輯:隨機生成 4 位字符,繪製干擾線,輸出 PNG 流,存入 Session,前端 <img> 標簽直接請求 Servlet 地址。
- @RequestMapping("/captcha.html")
- public void captcha(HttpServletResponse response, HttpServletRequest request) throws Exception {
- response.setContentType("image/png");
- response.setHeader("Pragma", "No-cache");
- response.setHeader("Cache-Control", "no-cache");
- response.setDateHeader("Expires", 0);
- int width = 80, height = 40;
- BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
- Graphics g = image.getGraphics();
- // 背景
- g.setColor(new Color(40, 200, 255));
- g.fillRect(0, 0, width, height);
- // 隨機字符池
- char[] chars = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890".toCharArray();
- Random random = new Random();
- StringBuilder code = new StringBuilder();
- // 繪製 4 個字符
- for (int i = 0; i < 4; i++) {
- char ch = chars[random.nextInt(chars.length)];
- g.setColor(new Color(random.nextInt(88), random.nextInt(188), random.nextInt(255)));
- g.setFont(new Font("微軟雅黑", Font.BOLD, 18));
- g.drawString(String.valueOf(ch), i * 15 + 3, 18);
- code.append(ch);
- }
- // 干擾線
- for (int i = 0; i < 20; i++) {
- g.setColor(new Color(random.nextInt(88), random.nextInt(188), random.nextInt(255)));
- g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
- }
- g.dispose();
- // 存入 Session
- request.getSession().setAttribute("captcha_code", code.toString());
- // 輸出圖片流
- ImageIO.write(image, "png", response.getOutputStream());
- }
- <img id="captchaImg" src="${pageContext.request.contextPath}/captcha.html" style="cursor:pointer;" title="點擊刷新" />
- <script>
- document.getElementById('captchaImg').onclick = function() {
- this.src = '${pageContext.request.contextPath}/captcha.html?' + new Date().getTime();
- };
- </script>
Pragma/No-cache、Cache-Control/no-cache、Expires=0,加隨機時間戳參數強制瀏覽器重新請求。session.getAttribute("captcha_code")。yum install fontconfig mkfontscale 並拷貝 msyh.ttc),否則中文顯示為方塊。
- @PostMapping("/login")
- public String login(@RequestParam String captcha, HttpSession session) {
- String real = (String) session.getAttribute("captcha_code");
- if (real == null || !real.equalsIgnoreCase(captcha)) {
- return "驗證碼錯誤";
- }
- // 校驗通過,清除驗證碼防重用
- session.removeAttribute("captcha_code");
- return "登入成功";
- }