图片验证码的简单生成与使用

139 阅读1分钟

图片验证码的简单生成

  • 利用CodeUtil生成验证码image对象以及验证码字符串
// CodeUtil.java源码
package com.qst.utils;


import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * @description: 验证码图片生成工具类
 * @author: ahh556
 * @createDate: 2022/6/24
 * @version: 1.0
 */
public class CodeUtil {
    /**
     * 获取验证码图片的image
     * @param width 图片宽度
     * @param height 图片高度
     * @param n 验证码长度
     * @param size 字体大小
     * @return 包含了验证码图片的Image对象与验证码字符串的map
     * @throws IOException
     */
    public static Map<String, Object> getImage(int width, int height, int n, int size) throws IOException {
        // 创建一个空白图片
        BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
        // 获取图片画笔
        Graphics g = image.getGraphics();
        // 设置随机数器
        Random r = new Random();
        // 设置画笔颜色
        g.setColor(new Color(r.nextInt(225),r.nextInt(225),r.nextInt(225)));
        // 填充矩形作为背景
        g.fillRect(0,0,width,height);
        // 获取验证码字符串
        String codeNum = getCodeNumber(n);
        // 画验证码
        g.setColor(new Color(r.nextInt(225),r.nextInt(225),r.nextInt(225)));
        g.setFont(new Font("Arial",Font.BOLD,size));
        g.drawString(codeNum,width / 2 - size * n / 2 / 2,height / 2 + size / 3);
        // 绘制8条干扰线
        for (int i = 0; i < n * 2; i++) {
            g.setColor(new Color(r.nextInt(225),r.nextInt(225),r.nextInt(225)));
            g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("BufferedImage",image);
        map.put("codeNum",codeNum);
        // 返回包含图片对象与验证码的map
        return map;

    }

    /**
     * 获取验证码图片的image
     * @width 图片宽度 默认为 100px
     * @height 图片高度 默认为 30 px
     * @n 验证码长度 默认为 4
     * @return 包含了验证码图片的Image对象与验证码字符串的map
     * @throws IOException
     */
    public static Map<String, Object> getImage() throws IOException {
        // 创建一个空白图片
        BufferedImage image = new BufferedImage(100, 30,BufferedImage.TYPE_INT_RGB);
        // 获取图片画笔
        Graphics g = image.getGraphics();
        // 设置随机数器
        Random r = new Random();
        // 设置画笔颜色
        g.setColor(new Color(r.nextInt(225),r.nextInt(225),r.nextInt(225)));
        // 填充矩形作为背景
        g.fillRect(0,0,100,30);
        // 获取验证码字符串
        String codeNum = getCodeNumber(4);
        // 画验证码
        g.setColor(new Color(r.nextInt(225),r.nextInt(225),r.nextInt(225)));
        g.setFont(new Font("Arial",Font.BOLD,20));
        g.drawString(codeNum,100 / 2 - 20 * 2 / 2,30 / 2  + 20 / 3);
        // 绘制8条干扰线
        for (int i = 0; i < 8; i++) {
            g.setColor(new Color(r.nextInt(225),r.nextInt(225),r.nextInt(225)));
            g.drawLine(r.nextInt(100),r.nextInt(30),r.nextInt(100),r.nextInt(30));
        }
        Map<String, Object> map = new HashMap<>();
        map.put("BufferedImage",image);
        map.put("codeNum",codeNum);
        // 返回包含图片对象与验证码的map
        return map;

    }

    /**
     * 获取验证码的字符串
     * @param n 字符串长度
     * @return 验证码字符串
     */
    private static String getCodeNumber(int n) {
        String codeNum = "";
        Random r = new Random();
        for (int i = 0; i < n; i++) {
            codeNum = codeNum + (r.nextInt(10) - 0);
        }
        return codeNum;
    }
}
  • 将验证码字符串存在session中
  • 之后在接下来的请求中通过session中的存储的验证码,验证 验证码 是否输入正确

CodeUtil.java的实际使用示例

后端代码

package com.qst.servlet;

import com.qst.utils.CodeUtil;

import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
import java.util.Random;

@WebServlet(name = "CodeServlet", value = "/code")
public class CodeServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Map<String, Object> map = CodeUtil.getImage();
        System.out.println("请求执行了" + map.get("codeNum"));
//         告诉浏览器解析成图片
        resp.setContentType("image/jpeg");
        OutputStream out = resp.getOutputStream();
        ImageIO.write((BufferedImage)map.get("BufferedImage"),"jpeg",out);
        out.close();

    }

}

前端代码

<%--
  Created by IntelliJ IDEA.
  User: 90894
  Date: 2022/6/24
  Time: 15:39
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--前端页面实现了点击验证码图片刷新,还有利用随机防止缓存--%>
<div><img src="code" onclick="this.src = 'code?' + Math.random()"></div>


</body>
</html>