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

yizhihongxing

下面我来详细讲解“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统计一个字符串在另外一个字符串出现次数的方法

    当需要统计一个字符串在另外一个字符串中出现的次数时,可以使用Java中的字符串处理方法来实现。下面将具体讲解如何进行操作。 一、先了解Java中的字符串方法 Java中的字符串类提供了一个indexOf(String str)方法,可以在一个字符串中查找指定的子串,并返回其在字符串中第一次出现的位置。如果查找不到目标字符串,则返回-1。 此外,还有一个类似的…

    Java 2023年5月27日
    00
  • JDBC数据源连接池配置及应用

    JDBC数据源连接池配置及应用是Web应用程序中常用的技术之一,可以提高系统性能并避免资源浪费。下面我将详细讲解JDBC数据源连接池配置及应用的完整攻略。 什么是JDBC数据源连接池? JDBC数据源连接池就是将数据库连接以池的方式进行管理,连接请求首先从连接池中获取连接,而不是每次都重新建立连接,从而提高系统性能并避免资源浪费。 如何进行JDBC数据源连接…

    Java 2023年6月15日
    00
  • Java 后端开发中Tomcat服务器运行不了的五种解决方案

    下面就详细讲解一下“Java 后端开发中Tomcat服务器运行不了的五种解决方案”的攻略。 问题描述 在Java后端开发中,经常会使用Tomcat服务器,但在部署过程中,可能会遇到Tomcat服务器运行不了的问题。这些问题可能有多种原因,接下来我们将逐一介绍五种解决方案。 解决方案 1.检查端口占用情况 Tomcat服务器默认使用的端口号为8080,如果该端…

    Java 2023年6月2日
    00
  • SpringMVC拦截器超详细解读

    以下是关于“SpringMVC拦截器超详细解读”的完整攻略,其中包含两个示例。 SpringMVC拦截器超详细解读 在SpringMVC中,拦截器是一种非常重要的组件,它可以在请求到达控制器方法之前或之后进行一些处理。本攻略将详细介绍SpringMVC拦截器的使用方法和注意事项。 拦截器的作用 拦截器可以在请求到达控制器方法之前或之后进行一些处理,如记录日志…

    Java 2023年5月16日
    00
  • JSON.parseObject和JSON.toJSONString实例详解

    JSON.parseObject和JSON.toJSONString实例详解 什么是JSON JSON全称为JavaScript Object Notation,是一种轻量级数据交换格式。 JSON由于其易读易写、数据格式比XML更简洁、转换速度更快等特性,在web应用中逐渐被广泛使用。 JSON.parseObject JSON.parseObject()…

    Java 2023年5月26日
    00
  • Spring Boot运行部署过程图解

    下面详细讲解一下“SpringBoot运行部署过程图解”的完整攻略。 简介 SpringBoot是基于Spring Framework的一款开源框架,目前已成为Java领域中的热门框架之一。SpringBoot的优势在于它可以快速简单的创建一个独立运行的、生产级别的Spring应用,而不需要以前的一些繁琐的配置。本文将介绍SpringBoot的运行部署过程,…

    Java 2023年5月15日
    00
  • SpringBoot控制配置类加载顺序方式

    SpringBoot是一个基于Spring框架的开源应用程序开发框架,主要用于快速构建基于Spring的企业级应用程序。而SpringBoot中一个非常重要的机制就是使用控制配置类进行应用程序的配置。控制配置类可以通过多种方式进行加载,这里我们就详细讲解一下SpringBoot控制配置类加载顺序方式以及相应实例。 控制配置类的加载顺序方式 SpringBoo…

    Java 2023年5月31日
    00
  • python实现JAVA源代码从ANSI到UTF-8的批量转换方法

    下面是“python实现JAVA源代码从ANSI到UTF-8的批量转换方法”的完整攻略: 1. 安装Python 如果你的电脑上还没有Python,需要先安装Python。 请前往 https://www.python.org/downloads/ 下载并安装Python。 2. 编写Python代码 接下来需要编写Python代码来实现批量转换功能。具体代…

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