jsp+Servlet编程实现验证码的方法

下面我来详细讲解“jsp+Servlet编程实现验证码的方法”的完整攻略。

什么是验证码?

验证码(CAPTCHA)是指计算机应用程序为区分用户是真实用户还是计算机程序而推出的一种测试。常见的验证码类型包括数字、字母、滑块等形式,用户需要正确地填写系统生成的图形码信息才能进行下一步操作。

实现验证码的原理

验证码的实现原理是利用了Web开发中的Session机制。当我们访问网站时,会话的ID会被存储在Web服务器端的存储器里。生成的验证码会放在一个Session中存储,并且在前端展示给用户。 用户提交表单时,后台会收到表单提交的数据及验证码,后台程序会从Session中取出验证码并与用户传输的验证码进行比较。如果输入的验证码不正确,后台程序可以拒绝接受表单数据。

实现步骤

在jsp页面中创建验证码的表单,并在后台通过Servlet生成验证码并存储到session中;通过判断session的值与用户输入的值是否一致,来实现验证码的验证。

具体的实现步骤:

  1. 创建验证码图片
    首先,我们需要生成一副随机的验证码图片,可以使用Java的Graphics类,在图片上写入验证码字符串,并增加一些干扰线和干扰点,以使验证码更加难以被识别。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    int width = 120;//定义图片宽度
    int height = 30;//定义图片高度
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//创建BufferedImage对象
    Graphics g = image.getGraphics();//创建Graphics对象
    //填充背景
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, width, height);
    //产生4个随机字符
    String text = "";
    String base = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    Random random = new Random();
    for (int i = 0; i < 4; i++) {
        //随机颜色
        g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
        //设置字体
        Font font = new Font("宋体", Font.BOLD, 25);
        g.setFont(font);
        //画字符
        char ch = base.charAt(random.nextInt(base.length()));
        g.drawString("" + ch, (20 * i) + 12, 24);
        text = text + ch;
    }
    //干扰线
    for (int i = 0; i < 5; i++) {
        g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
        g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
    }
    //干扰点
    for (int i = 0; i < 30; i++) {
        g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
        g.drawOval(random.nextInt(width), random.nextInt(height), 1, 1);
    }
    //将验证码存入Session
    request.getSession().setAttribute("checkcode", text);
    //response
    response.setContentType("image/jpeg");
    OutputStream os = response.getOutputStream();
    ImageIO.write(image, "jpeg", os);
}
  1. 在jsp页面中使用img标签显示验证码图片
<%@page contentType="text/html;charset=UTF-8" language="java"%>
<html>
<head>
    <meta charset="UTF-8">
    <title>验证码示例</title>
</head>
<body>
    <form action="RegisterServlet" method="post">
        <label>用户名:</label>
        <input name="username"><br>
        <label>密码:</label>
        <input name="password" type="password"><br>
        <label>验证码:</label>
        <input name="checkcode">
        <img src="CheckCodeServlet" alt="验证码" onclick="this.src='CheckCodeServlet?d='+new Date().getTime()"><br>
        <input type="submit" value="注册">
    </form>
</body>
</html>

其中,img标签的src属性指向CheckCodeServlet的地址,onclick事件用来更新验证码图片。

  1. 在Servlet中获取并验证用户输入的验证码
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //获取输入的用户名、密码和验证码
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String checkcode = request.getParameter("checkcode");
    //从Session中获取验证码
    String code = (String) request.getSession().getAttribute("checkcode");
    //比较验证码
    if(code.equalsIgnoreCase(checkcode)){
        //验证码正确,进行注册操作
        //...
    }else {
        //验证码错误,返回错误提示
        response.getWriter().write("验证码错误!");
    }
}
  1. 防止验证码过期

由于Session的默认过期时间比较短,验证码可能会在过期时间内失效,从而导致验证码验证失败。可以通过在Servlet中设置Session的有效时间来解决这个问题:

@Override
public void init(FilterConfig filterConfig) throws ServletException {
    //在初始化时获取配置的过期时间
    String timeout = filterConfig.getInitParameter("timeout");
    //将timeout转换为long类型
    sessionTimeout = Long.parseLong(timeout);
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest)servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    //获取Session
    HttpSession session = request.getSession();
    //设置Session的过期时间为30分钟
    session.setMaxInactiveInterval((int)sessionTimeout);
    filterChain.doFilter(request,response);
    return;
}

示例说明

以下是两条完整的示例说明。

示例一:验证码登陆

如果我们要实现用户登录的时候需要输入验证码,可以在登录表单中加入验证码的输入框,并在后端进行验证码的验证。

登陆表单样式:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
    <center>
        <h2>Welcome</h2>
        <form method="post" action="loginServlet">
            <table>
                <tr>
                    <td>UserName:</td>
                    <td><input type="text" name="username"/></td>
                </tr>
                <tr>
                    <td>Password:</td>
                    <td><input type="password" name="password"/></td>
                </tr>
                <tr>
                    <td>Code:</td>
                    <td><input type="text" name="checkcode"/><img src="CodeServlet" onclick="this.src='CodeServlet?'+new Date().getTime();"/></td>
                </tr>
                <tr>
                    <td colspan="2" align="right"><input type="submit" value="Login"/></td>
                </tr>
            </table>
        </form>
    </center>
</body>
</html>

CodeServlet代码:

package com.myblog.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * Created by gjy on 2021/7/6
 **/
@WebServlet(name = "CodeServlet", urlPatterns = "/CodeServlet")
public class CodeServlet extends HttpServlet {

    private static final long serialVersionUID = 2432440348832509368L;

    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        int width = 120;
        int height = 25;
        // 创建BufferedImage对象,设置大小和参数设置
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        // 创建一个随机数生成器
        int codeCount = 4;// 验证码长度为4
        char code[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray();
        // 创建一个字符串,用于存储生成的验证码
        StringBuffer buffer = new StringBuffer();
        // 将验证码绘制到图像中
        // randomCode用于保存随机产生的验证码,以便用户登录后进行验证
        String randomCode = null;
        for (int i = 0; i < codeCount; i++) {
            // 得到随机产生的验证码数字
            String strRand = String.valueOf(code[new Random().nextInt(code.length)]);
            // 用随机产生的颜色将验证码绘制到图像中
            g2d.setColor(new Color(new Random().nextInt(255),
                    new Random().nextInt(255), new Random().nextInt(255)));
            g2d.drawString(strRand, 18 * i + 10, 19);
            buffer.append(strRand);
        }
        // 将生成的验证码保存到session中,跟用户的输入进行比较
        HttpSession session = request.getSession();
        session.setAttribute("checkcode", buffer.toString());
        g2d.dispose();

        response.setContentType("image/jpeg");
        OutputStream outputStream = response.getOutputStream();
        // 输出图像到页面
        ImageIO.write(image, "jpeg", outputStream);
        outputStream.close();
    }

    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

loginServlet代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String checkcode = request.getParameter("checkcode");
    HttpSession session = request.getSession();
    String trueCode = session.getAttribute("checkcode").toString();
    if (checkcode == null || !trueCode.equals(checkcode)) {// 判断验证码是否输入正确
        response.sendRedirect("check.html");
        return;
    }
    System.out.println("The userName is " + username);
    System.out.println("The password is " + password);
    response.sendRedirect("login.jsp");
}

示例二:实现验证码注册

在使用表单进行用户注册时,我们也可以添加验证码输入框,以便验证。

注册页面样式:

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Register</title>
</head>
<body>
    <h2>Register</h2>
    <form action="RegisterServlet" method="post">
        <table>
            <tr>
                <td><label for="username">Username:</label></td>
                <td><input type="text" id="username" name="username" required></td>
            </tr>
            <tr>
                <td><label for="password">Password:</label></td>
                <td><input type="password" id="password" name="password" required></td>
            </tr>
            <tr>
                <td><label for="checkcode">Verification Code:</label></td>
                <td>
                    <input type="text" id="checkcode" name="checkcode" required>
                    <img src="CodeServlet" onclick="this.src='CodeServlet?' + new Date().getTime();"/>
                </td>
            </tr>
            <tr>
                <td colspan="2" align="center">
                    <input type="submit" value="Register">
                </td>
            </tr>
        </table>
    </form>
</body>
</html>

CodeServlet代码和上面示例一相同,就不再给出。

RegisterServlet代码:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    String username = request.getParameter("username");
    String password = request.getParameter("password");
    String checkcode = request.getParameter("checkcode");
    HttpSession session = request.getSession();
    String trueCode = session.getAttribute("checkcode").toString();
    if (checkcode == null || !trueCode.equals(checkcode)) {// 判断验证码是否输入正确
        response.getWriter().append("Incorrect Verification Code!");
        return;
    }
    System.out.println("The userName is " + username);
    System.out.println("The password is " + password);
    response.getWriter().append("Register Success!");
}

总结

至此,“jsp+Servlet编程实现验证码的方法”已经说完了。通过本文,我们了解了验证码的作用与实现原理,并详细讲解了如何通过JSP和Servlet技术实现验证码。对于Web开发中需要验证用户身份的场景,使用验证码是保证安全性的一种常用方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:jsp+Servlet编程实现验证码的方法 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • java编写简单的E-mail发送端程序

    下面来详细讲解一下“Java编写简单的E-mail发送端程序”的完整攻略。 1. 准备工作 确保计算机安装了Java开发环境(JDK) 下载JavaMail API包和Java Activation Framework包,并将其添加到项目的classpath中 2. 导入必要的包 使用JavaMail API发送邮件需要导入以下包: import javax…

    Java 2023年5月23日
    00
  • 如何把JAR发布到maven中央仓库的几种方法

    下面是如何将JAR包发布到Maven中央仓库的几种方法的完整攻略: 方法一:使用Maven发布插件 首先,在你的项目中加入Maven发布插件: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <art…

    Java 2023年5月20日
    00
  • javaWeb 四大域对象详细介绍

    JavaWeb 四大域对象详细介绍 在 JavaWeb 中,有四个重要的域对象,分别是 应用程序域对象、会话域对象、请求域对象和页面域对象。这些域对象的作用是为了在 Web 应用程序中共享数据。 应用程序域对象 (ServletContext) 应用程序域对象是在整个 Web 应用程序中是共享的,存在于整个应用程序的生命周期中。根据 Servlet 规范,每…

    Java 2023年5月26日
    00
  • SpringBoot 钩子接口的实现代码

    在SpringBoot中,我们可以通过实现钩子接口(Hook Interface)来在启动应用程序或者关闭应用程序时执行一些特定的逻辑行为。例如我们可以在应用启动时预加载某些资源,或者在应用关闭时清理一些资源等。本文将为大家介绍如何实现SpringBoot钩子接口,包含以下步骤: 新建Hook Interface 首先,我们需要新建一个Hook Interf…

    Java 2023年5月31日
    00
  • java生成随机字符串的两种方法

    下面是“Java生成随机字符串的两种方法”的详细讲解: 方法一:使用Java自带的Random类生成随机字符串 Java自带的Random类可以用来生成随机数,利用这个随机数可以生成随机字符串。下面是实现代码: import java.util.Random; public class RandomStringGenerator { private stat…

    Java 2023年5月26日
    00
  • Java实现酒店客房管理系统

    Java实现酒店客房管理系统完整攻略 需求分析 在进行项目的开发之前,需要先对客户的需求进行分析,明确需要实现的功能。 客房管理:包括房间类型、房间编号、房间状态(已入住、空闲、维修中),查询、添加、删除、修改客房信息等; 客户管理:包括客户姓名、身份证号、联系方式、入住时间等信息; 订单管理:包括下单、取消订单、订单查询等; 财务管理:客户结账等。 数据库…

    Java 2023年5月23日
    00
  • Java Optional解决空指针异常总结(java 8 功能)

    Java 8 中引入了一个新的类 Optional,用于解决空指针异常问题。本篇攻略将会详细介绍 Optional 类的使用方法和相关注意事项。 理解 Optional 类 Optional 是一个容器,用于表示一个值存在或不存在的情况。如果某个函数返回一个 Optional 类型的对象,我们就可以判断其是否为空,避免了空指针异常的发生。 Optional …

    Java 2023年5月25日
    00
  • 手动添加jar包进Maven本地库内的方法

    当我们在使用 Maven 构建项目时,有可能会遇到需要使用本地 Jar 包的情况。这时我们需要手动将 Jar 包添加到 Maven 本地库中。下面是完整的手动添加 Jar 包到 Maven 本地库的攻略: 1. 确定 Maven 本地库的位置 首先我们需要确定 Maven 本地库的位置。我们可以在 Maven 的 settings.xml 文件中查看本地库的…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部