15-HTTP-response验证码的实现

验证码(CAPTCHA)通常是一种图像形式的测试,用于防止恶意程序或机器人自动提交表单等非人工操作。验证码可以有效地减少不必要的垃圾信息和恶意行为。

  1. 生成四位随机数字作为验证码。
  2. 用Font、Graphics和Random类创建图片缓冲区对象BufferedImage,并在图片上绘制验证码。
  3. 将图片显示在前端页面上并记录正确的验证码信息。
  4. 添加点击事件切换验证码,每点击一次就更换验证码。
  5. 验证用户输入的验证码是否正确,如果错误则记录错误次数,最多允许三次错误输入。
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

public class CaptchaServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // 验证码宽度
    private static final int WIDTH = 100;
    // 验证码高度
    private static final int HEIGHT = 30;
    // 验证码字符数
    private static final int LENGTH = 4;
    // 验证码字体大小
    private static final int FONT_SIZE = 24;
    // 允许的最多错误次数
    private static final int MAX_ERRORS = 3;

    private String verifyCodeChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private Random random = new Random();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 设置响应内容类型
        response.setContentType("image/jpeg");
        // 禁止图像缓存
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        StringBuilder captcha = new StringBuilder();
        // 绘制背景色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 绘制验证码字符串
        for (int i = 0; i < LENGTH; i++) {
            int randomIndex = random.nextInt(verifyCodeChars.length());
            String randomChar = verifyCodeChars.substring(randomIndex, randomIndex + 1);
            captcha.append(randomChar);
            Font font = new Font(Font.MONOSPACED, Font.BOLD, FONT_SIZE);
            g.setFont(font);
            g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            FontRenderContext context = g.getFontRenderContext();
            TextLayout textLayout = new TextLayout(randomChar, font, context);
            float x = (i * WIDTH / LENGTH) + (WIDTH / LENGTH - textLayout.getAdvance()) / 2;
            float y = HEIGHT / 2 + textLayout.getAscent() / 2;
            textLayout.draw(g, x, y);
        }

        // 记录正确验证码信息
        request.getSession().setAttribute("captcha", captcha.toString());

        // 释放图形资源
        g.dispose();

        // 将图片输出到响应流中
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpeg", out);
        out.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String inputCaptcha = request.getParameter("captcha");
        String captcha = (String) request.getSession().getAttribute("captcha");

        // 验证用户输入的验证码是否正确,如果错误则记录错误次数
        int errorCount = 0;
        if (inputCaptcha != null && !"".equals(inputCaptcha)) {
            if (!inputCaptcha.equals(captcha)) {
                errorCount++;
                request.setAttribute("errorMsg", "验证码错误");
            }
        }

        // 如果错误次数达到上限,则禁止继续验证
        if (errorCount >= MAX_ERRORS) {
            request.setAttribute("errorMsg", "您已连续错误三次,不能再进行验证!");
            request.getRequestDispatcher("/error.jsp").forward(request, response);
        } else {
            request.getRequestDispatcher("/register.jsp").forward(request, response);
        }
    }
}

在web.xml中添加servlet映射:

<servlet>
    <servlet-name>CaptchaServlet</servlet-name>
    <servlet-class>CaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>CaptchaServlet</servlet-name>
    <url-pattern>/captchaServlet</url-pattern>
</servlet-mapping>

在前端页面中添加验证码显示和点击事件:

<img src="captcha.jpg" alt="验证码" onclick="changeCaptcha()">

<script>
    function changeCaptcha() {
        var img = document.getElementsByTagName("img")[0];
        img.src = "captcha.jpg?" + Math.random();
    }
</script>

这里使用了getElementsByTagName方法获取页面上第一个img元素,并将其src属性中的随机数改变以达到刷新验证码的效果。同时,在HTML中给标签设置了onclick属性,当用户点击该标签时,会调用changeCaptcha函数来切换验证码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值