天天看点

java 动态生成验证码

作者:Starboy梦

运行环境:

IDEA:2021.2.4

Tomcat 服务器:Tomcat 8.5.81

JDK:java1.8.0

搭建 JavaWeb 环境,不详细解说了,因为这很基础!

开始干活吧!

今天我们要创建 2个类【生成验证码类、Servlet类】以及一个显示二维码的 jsp 文件

先简单说明一下,这是我的一个实验中的一个小功能【核心】

这是我的工程结构目录:(仅供参考)

java 动态生成验证码

我们今天的主角就是其中的三个文件:

  1. servlet 包下的 GenerateCodeServlet 主要功能:响应我们的浏览器请求,并调用ValidateCode 这个Java类去生成验证码
  2. validate 包下的 ValidateCode 类,主要功能:生成我们的验证码图片
  3. web 包下的 ValidateCode.jsp ,显示我们的验证码

首先创建我们的 ValidateCode 类

代码参考:

package com.fly.code.validate;

import jdk.internal.util.xml.impl.Input;
import org.junit.Test;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * @author: fly
 * @Date: 2023-03-24 8:52
 * @Description:
 *  1. 实现动态生成验证码字符串
 *  2. 验证码可使用大小写字母+数字的形式
 */
public class ValidateCode {

    public static int randomNumber(String str) {
        return (int) Math.floor(Math.random()*str.length());
    }

    /**
     * 动态生成验证码字符串 【数字+字母(大小写)】
     * @return 4位随机验证码
     */
    public static String generateCode(){
        // 从该字符串随机抽取 4 个字符
        String libs = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
        StringBuilder buffer = new StringBuilder();
        for (int i = 0;i < 4;i++) {
            char ch = libs.charAt(randomNumber(libs));
            buffer.append(ch);
        }
        return String.valueOf(buffer);
    }

    /**
     * 生成图片
     */
    public static BufferedImage createImage(String code,String path,int imageWid,int imageHei,int imageType) {
        BufferedImage image = new BufferedImage(imageWid,imageHei,imageType);

        Graphics2D graph;

        graph =  image.createGraphics();
        // 设置背景色
        graph.setBackground(Color.WHITE);
        // 设置背景颜色填充范围
        graph.fillRect(0,0,imageWid,imageHei);
        // 设置画笔颜色
        graph.setColor(Color.BLACK);
        // 设置字体大小
        graph.setFont(new Font("微软雅黑", Font.PLAIN, 25));
        // graph.drawLine(0,16,imageWid,16);
        graph.drawString(code,imageWid/5,25);

        // 保存图片
        try {
            ImageIO.write(image,"JPG",new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }

        return image;
    }

    /**
     * 保存图片
     */
    public static void save(String savePath,String filepath,HttpServletRequest request) {
        InputStream is = null;
        OutputStream os = null;

        byte[] buffer = new byte[1024];
        int len = 0;

        try {
            is = new FileInputStream(filepath);
            os = new FileOutputStream(savePath);

            while((len = is.read(buffer)) != -1) {
                os.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}           

其中,没有用到保存图片这个方法(save)哦~

接着创建我们的 GenerateCodeServlet 类

代码:

package com.fly.code.servlet; /**
 * @author: fly
 * @Date: 2023-03-24 9:12
 * @Description: 返回验证码图片
 */

import com.fly.code.validate.ValidateCode;
import org.apache.tomcat.jni.Time;
import org.junit.Test;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Properties;
import java.util.UUID;

@WebServlet(name = "GenerateCodeServlet", value = "/generateCodeServlet")
public class GenerateCodeServlet extends HttpServlet {

    private static final String BASE_URL = "D:\\学习2\\大三下\\物联网平台应用设计\\实验4";

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取随机验证码
        String code = ValidateCode.generateCode();
        // HttpSession对象存储验证码
        HttpSession session = request.getSession();
        session.setAttribute("code",code);
        // BufferedImage(一个带缓冲区图像类)将生成的验证码图片存到一个图像缓冲区
        String uuid = String.valueOf(UUID.randomUUID());
        uuid = uuid.replaceAll("-","");
        session.setAttribute("uuid",uuid);
        String path = "/validate-code/" + uuid + ".jpg";
        String realPath = request.getServletContext().getRealPath(path);
        // 创建二维码图片,并保存到 /validate-code 目录下
        ValidateCode.createImage(code,realPath,100,32,BufferedImage.TYPE_INT_RGB);
        try {
            // 等待图片生成完毕
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 重定向到登录页面
        response.sendRedirect("/test/ValidateCode.jsp");
    }
}
           

最后收尾阶段,创建jsp文件

代码:

<%@ page import="java.io.*" %><%--
  Created by IntelliJ IDEA.
  User: local-feng
  Date: 2023/3/24
  Time: 10:19
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>验证码图片显示</title>
</head>
<body>
    <%
        String uuid = (String) session.getAttribute("uuid");
        String path = "/validate-code/" + uuid + ".jpg";
        path = request.getContextPath() + path;
    %>
    <img src="<%=path%>" title="验证码" alt="验证码">
</body>
</html>           

好了,运行我们的 Tomcat 容器吧!

Tomcat 配置如下:

java 动态生成验证码

访问我们的网址:http://localhost:8023/test/generateCodeServlet

在等待 5秒的 验证码图片生成后,我们在浏览器成功看到验证码

java 动态生成验证码

我们在文件资源管理器中也能够看到我们生成的验证码图片:

java 动态生成验证码

拓展小知识:

有了验证码,我们可以做什么呢?当然是,登录页面啦!

搞懂这个动态生成验证码,你也可以做出登录页面!

可能网上不是我这种生成验证码,因为这种方式太慢了,需要等待验证码图片的生成时间。

比如:这样的!这是我们课堂上的实验 【当然,界面没有仔细美化就是了】

java 动态生成验证码