java web开发之servlet图形验证码功能的实现

图形验证码(Captcha)是一种用于区分用户是机器人还是人类的测试。它通常用于网站注册、评论等功能。Java Web开发中,我们可以使用Servlet来实现图形验证码的功能,下面就来介绍一下如何实现。

[TOC]

介绍

图形验证码(Captcha)是一种用于区分用户是机器人还是人类的测试。它通常用于网站注册、评论等功能。Java Web开发中,我们可以使用Servlet来实现图形验证码的功能,下面就来介绍一下如何实现。

实现步骤

以下是Servlet实现图形验证码的完整步骤:

  1. 创建验证码图片
  2. 将验证码图片输出到页面
  3. 将验证码传入Session中
  4. 验证用户输入是否与Session中的验证码匹配

下面我们逐步来讲解。

创建验证码图片

先来看一下示例代码:

public class CaptchaServlet extends HttpServlet {
    private int width = 100;//验证码图片的宽度
    private int height = 40;//验证码图片的高度
    private int codeCount = 4;//验证码字符个数
    private int lineCount = 150;//干扰线个数

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImg.createGraphics();
        Random random = new Random();

        // 设置背景色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);

        // 设置字体
        Font font = new Font("Fixedsys", Font.BOLD, 28);
        g.setFont(font);

        // 设置干扰线
        for (int i = 0; i < lineCount; i++) {
            int xs = random.nextInt(width);
            int ys = random.nextInt(height);
            int xe = xs + random.nextInt(width / 8);
            int ye = ys + random.nextInt(height / 8);
            g.setColor(getRandomColor());
            g.drawLine(xs, ys, xe, ye);
        }

        // 设置验证码
        String code = "";
        for (int i = 0; i < codeCount; i++) {
            String str = String.valueOf(random.nextInt(10));
            code += str;
            g.setColor(getRandomColor());
            g.drawString(str, 25 * i + 10, 30);
        }

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

        // 将验证码保存在session中
        HttpSession session = request.getSession();
        session.setAttribute("code", code);

        response.setContentType("image/jpeg");// 设置响应的类型格式为图片格式
        OutputStream os = response.getOutputStream();// 得到向客户端输出图片的流
        ImageIO.write(buffImg, "jpeg", os);// 输出图片流
        os.close();
    }

    private Color getRandomColor() {
        Random random = new Random();
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }
}

CaptchaServlet是我们创建的Servlet,其中doGet方法用于处理GET请求,它会创建一个BufferedImage对象,并在该对象上绘制验证码图片。在实现绘制验证码的代码中,我们首先设置了背景色为白色,并填充整个图片;然后设置字体为Fixedsys,字号为28;接着绘制干扰线[1],最后在图片上绘制随机生成的验证码,把它保存到session中。

将验证码图片输出到页面

在前面的示例中,我们已经将生成的验证码保存到了Session中。此时我们需要将验证码图片输出到页面,让用户能够看到它。

在HTML页面中,添加一个类似于下面的img标签:

<img src="CaptchaServlet" onclick="this.src='CaptchaServlet?'+new Date().getTime()">

当用户首次访问该页面时,CaptchaServlet会生成验证码图片并输出到页面上。当用户点击该图片时,this.src会发生变化,具体来说,它会在原来的URL后面加上一个时间戳,这样浏览器就会认为这是一个新的URL,重新请求该URL,CaptchaServlet就会生成新的验证码图片并输出到页面上。

将验证码传入Session中

在生成验证码图片的时候,我们已经将验证码保存到Session中了。在该Session中,我们可以使用getAttribute方法来获取保存的验证码。

验证用户输入是否与Session中的验证码匹配

当用户提交页面表单时,我们需要验证用户输入的验证码是否与Session中保存的验证码匹配。具体来说,我们可以使用类似于下面的代码进行比较:

String code = (String) session.getAttribute("code");
if (code.equals(userInputCode)) {
    // 验证码正确
} else {
    // 验证码错误
}

示例

下面是两个代码示例,分别实现了使用Servlet生成图形验证码和验证用户输入。

示例一:生成图形验证码

以下是实现生成图形验证码的代码示例:

<!-- captcha.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>验证码示例</title>
</head>
<body>
    <form>
        <label>验证码:</label>
        <img src="CaptchaServlet" onclick="this.src='CaptchaServlet?'+new Date().getTime()">
        <br>
        <label>验证码输入:</label>
        <input type="text" name="captcha">
        <br>
        <button type="submit">提交</button>
    </form>
</body>
</html>
// CaptchaServlet.java
@WebServlet("/CaptchaServlet")
public class CaptchaServlet extends HttpServlet {
    private int width = 100;//验证码图片的宽度
    private int height = 40;//验证码图片的高度
    private int codeCount = 4;//验证码字符个数
    private int lineCount = 150;//干扰线个数

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = buffImg.createGraphics();
        Random random = new Random();

        // 设置背景色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);

        // 设置字体
        Font font = new Font("Fixedsys", Font.BOLD, 28);
        g.setFont(font);

        // 设置干扰线
        for (int i = 0; i < lineCount; i++) {
            int xs = random.nextInt(width);
            int ys = random.nextInt(height);
            int xe = xs + random.nextInt(width / 8);
            int ye = ys + random.nextInt(height / 8);
            g.setColor(getRandomColor());
            g.drawLine(xs, ys, xe, ye);
        }

        // 设置验证码
        String code = "";
        for (int i = 0; i < codeCount; i++) {
            String str = String.valueOf(random.nextInt(10));
            code += str;
            g.setColor(getRandomColor());
            g.drawString(str, 25 * i + 10, 30);
        }

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

        // 将验证码保存在session中
        HttpSession session = request.getSession();
        session.setAttribute("code", code);

        response.setContentType("image/jpeg");// 设置响应的类型格式为图片格式
        OutputStream os = response.getOutputStream();// 得到向客户端输出图片的流
        ImageIO.write(buffImg, "jpeg", os);// 输出图片流
        os.close();
    }

    private Color getRandomColor() {
        Random random = new Random();
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }
}

在该示例中,当用户访问captcha.html时,该页面会自动请求CaptchaServlet,从而生成验证码图片并显示在该页面上。

示例二:验证用户输入

以下是实现验证用户输入的代码示例:

<!-- validate.html -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>验证码示例</title>
</head>
<body>
    <form action="ValidateServlet" method="post">
        <label>验证码:</label>
        <img src="CaptchaServlet" onclick="this.src='CaptchaServlet?'+new Date().getTime()">
        <br>
        <label>验证码输入:</label>
        <input type="text" name="captcha">
        <br>
        <button type="submit">提交</button>
    </form>
</body>
</html>
// ValidateServlet.java
@WebServlet("/ValidateServlet")
public class ValidateServlet extends HttpServlet{
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();

        HttpSession session = request.getSession();
        String serverCode = (String) session.getAttribute("code");
        String userInputCode = request.getParameter("captcha");

        if (serverCode.equals(userInputCode)) {
            out.println("验证码输入正确!");
        } else {
            out.println("验证码输入错误!请重新输入!");
        }

        out.flush();
        out.close();
    }
}

在该示例中,当用户提交表单时,请求会发送到ValidateServlet,该Servlet需要从Session中获取生成的验证码,然后将用户输入的验证码与Session中的验证码进行比较,最后返回比较结果。

结论

本文介绍了使用Java Servlet实现图形验证码功能的完整攻略。当用户在浏览器中看到需要输入验证码时,通常需要访问Servlet生成验证码图片,将图片展示在页面上,等待用户输入。当用户提交表单后,需要将用户输入的验证码从表单中提交到Servlet中,在Servlet中可以将表单数据与Session中保存的验证码进行比较以验证验证码是否输入正确。这样就可以达到防止机器人攻击的目的。

本文标题为:java web开发之servlet图形验证码功能的实现

基础教程推荐