Java Servlet 验证码 实现

servlet学习练习

代码里面的注释够详细了,不多说了,有需要的转载请留意底部,如果帮到你了,点个赞呗(点赞又不收费)

纯手写练习,建议不要直接copy,动手敲一遍

源码下载链接

结果:

本机运行地址和配置:localhost:8080/s/caponee
在这里插入图片描述
servlet里面自己打印的信息
生成的验证码

完了直接去session里get出来CAPTCHA_CODE就可以验证了

package com.crazy.servlet;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

/**
 * @Description 验证码一:个位数+-*运算
 * @Author Crazy
 * @Date 2020/6/17-21:11
 * @Copyright Home
 */
public class CaptchaOneServlet extends HttpServlet {
    public static final String CAPTCHA_KEY = "CAPTCHA_CODE";

    Random random = new Random();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(">>>开始生成验证码:10以内+-*法运算");
        //页面缓存设置为不缓存
        resp.setHeader("Pragma", "No-cache");
        resp.setHeader("Cache-Control", "no-cache");
        resp.setDateHeader("Expires", 0);
        resp.setContentType("image/jpeg");

        //验证码图像大小px
        int width = 150, height = 45;
        //干扰线数量
        int interfereLineNum = 50;
        //运算符字体
        String fontString = "楷体";
        //验证码字符串大小
        int fontSize = 25;

        //创建图像
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //要生成的图形上下文并设置随机颜色
        Graphics2D graphics2D = image.createGraphics();
        graphics2D.setColor(getRandomColor(190, 255));
        //填充矩形
        graphics2D.fillRect(0, 0, width, height);

        //设置字体
        Font font = new Font(fontString, Font.PLAIN, fontSize);
        graphics2D.setFont(font);

        //画点干扰线
        for (int i = 0; i < interfereLineNum; i++) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xx = random.nextInt(200);
            int yy = random.nextInt(180);
            //颜色也随机一下
            graphics2D.setColor(getRandomColor());
            graphics2D.drawLine(x, y, x + xx, y + yy);
        }

        //验证码10以内 + - * 运算
        int num1 = (int) ((Math.random() * 10) + 1);
        int num2 = (int) ((Math.random() * 10) + 1);
        //运算方式随机
        int s = random.nextInt(3);
        String operationName = "";
        //运算的结果
        int result = 0;
        switch (s) {
            case 0:
                operationName = "加";
                result = num1 + num2;
                break;
            case 1:
                operationName = "减";
                result = (num1 - num2) > 0 ? (num1 - num2) : (num2 - num1);
                break;
            case 2:
                operationName = "乘";
                result = num1 * num2;
                break;
            default:
                break;
        }
        //写在图片中的字符串验证码运算
        String code = operationName == "减" ?
                ((num1 - num2) > 0 ? (num1 + operationName + num2 + "=?")
                        : (num2 + operationName + num1 + "=?"))
                : (num1 + operationName + num2 + "=?");
        graphics2D.setColor(new Color(22 + random.nextInt(150), 22 + random.nextInt(150), 22 + random.nextInt(150)));

        FontRenderContext context = graphics2D.getFontRenderContext();
        Rectangle2D rectangle2D = font.getStringBounds(code, context);
        //验证码字符串在图片中坐标计算
        double x = (width - rectangle2D.getWidth()) / 2;
        double y = (height - rectangle2D.getHeight()) / 2;
        double upY = -rectangle2D.getY();
        double baseY = y + upY;

        graphics2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        graphics2D.drawString(code, (int) x > 0 ? (int) x : 1, (int) baseY);

        //存验证码到session
        req.getSession().setAttribute(CAPTCHA_KEY, String.valueOf(result));
        System.out.println(">>>生成的验证码:" + code + ",已经存入session中key=" + CAPTCHA_KEY + "   value=" + result);

        //图像生效、释放此图形的上下文并释放它所使用的所有系统资源
        graphics2D.dispose();
        //输出到页面
        ImageIO.write(image, "jpeg", resp.getOutputStream());
        resp.getOutputStream().flush();

    }

    /**
     * 生成随机的颜色(根据传入的两个整数1-255值取色,两数差值越小 颜色越亮)
     *
     * @param a
     * @param b
     * @return Color
     */
    private Color getRandomColor(int a, int b) {
        int col = 255;
        if (a > col) {
            a = col;
        }
        if (b > col) {
            b = col;
        }
        Color color = new Color(a + random.nextInt(b - a), a + random.nextInt(b - a), a + random.nextInt(b - a));
        return color;
    }

    /**
     * 完全随机的颜色
     *
     * @return
     */
    private Color getRandomColor() {
        return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

声明:
博客中标注原创的文章,版权归本博客作者所有,若转载或者引用本文内容请注明来源及原作者,否则依法保留追究权
打赏功能被文章底部的···默认隐藏了,如果帮到你了点个赞呗【嘘~~~悄悄话:打赏的是大佬】

猜你喜欢

转载自blog.csdn.net/m0_48373030/article/details/106932272