写在前面

这里写了三种实现,可根据实际需要,选择之一,还有这里只是生成了验证码,具体校验方式可通过session,Redis等作存储、校验,这里就不介绍太多。

一、JDK原生包中Graphics对象,(java.awt.*),不需额外引包

1.1、封装对象 ImageCode

@Data
public class ImageCode {
   

    private BufferedImage image;
    private String code;
    private LocalDateTime expireTime;

    public ImageCode(BufferedImage image, String code, int expireIn) {
   
        this.image = image;
        this.code = code;
        this.expireTime = LocalDateTime.now().plusSeconds(expireIn);
    }

    public ImageCode(BufferedImage image, String code, LocalDateTime expireTime) {
   
        this.image = image;
        this.code = code;
        this.expireTime = expireTime;
    }

    public boolean isExpire() {
   
        return LocalDateTime.now().isAfter(expireTime);
    }

}

1.2、生成图片验证码,构造到上文创建的对象中

 @Test
    public void t1() throws IOException {
   
        ImageCode imageCode = createImageCode();

// 写到控制台乱码
// ImageIO.write(imageCode.getImage(), "jpeg", System.out);

        ImageIO.write(imageCode.getImage(), "jpeg", Files.newOutputStream(new File("d:/ee.jpeg").toPath()));
    }

    private ImageCode createImageCode() {
   

        int width = 120; // 验证码图片宽度
        int height = 45; // 验证码图片长度
        int length = 4; // 验证码位数
        int expireIn = 60; // 验证码有效时间 60s

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics g = image.getGraphics();

        Random random = new Random();

        g.setColor(getRandColor(185, 250));
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Times New Roman", Font.ITALIC, 35));
        g.setColor(getRandColor(160, 200));
        for (int i = 0; i < 155; i++) {
   
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);
        }

        StringBuilder sRand = new StringBuilder();
        for (int i = 0; i < length; i++) {
   
            String rand = String.valueOf(random.nextInt(10));
            sRand.append(rand);
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            g.drawString(rand, 25 * i + 12, 32);
        }

        g.dispose();

        return new ImageCode(image, sRand.toString(), expireIn);
    }

    private Color getRandColor(int fc, int bc) {
   
        Random random = new Random();
        if (fc > 255)
            fc = 255;

        if (bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

1.3、图片验证码,如下,具体大小,参数,图纹,背景等可细调整

二、google 封装的开源包,引入相关依赖

先引入依赖

   <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
   </dependency>

2.1、需要配置类

import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

@Configuration
public class KaptchaConfig {
   

    @Bean
    public Producer KaptchaProducer() {
   
        Properties kaptchaProperties = new Properties();
        kaptchaProperties.put("kaptcha.border", "no");
        kaptchaProperties.put("kaptcha.textproducer.char.length","4");
        kaptchaProperties.put("kaptcha.image.height","50");
        kaptchaProperties.put("kaptcha.image.width","150");
        kaptchaProperties.put("kaptcha.obscurificator.impl","com.google.code.kaptcha.impl.ShadowGimpy");
        kaptchaProperties.put("kaptcha.textproducer.font.color","black");
        kaptchaProperties.put("kaptcha.textproducer.font.size","40");
        kaptchaProperties.put("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise");
        //kaptchaProperties.put("kaptcha.noise.impl","com.google.code.kaptcha.impl.DefaultNoise");
        kaptchaProperties.put("kaptcha.textproducer.char.string","acdefhkmnprtwxy2345678");

        Config config = new Config(kaptchaProperties);
        return config.getProducerImpl();
    }
}

2.1、代码生成,注入SpringBean,测试

 @Autowired
    private Producer captchaProducer;

 @GetMapping("/captcha")
    public void captcha() throws IOException {
   

        // create the text for the image 
        String capText = captchaProducer.createText();

        // create the image with the text 
        BufferedImage bi = captchaProducer.createImage(capText);

        ImageIO.write(bi, "jpeg", Files.newOutputStream(new File("d:/google.jpeg").toPath()));
    }

2.3、图片验证码,如下,也可细调

||

三、Hutool 开源包,引入相关依赖

先引入依赖

     <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.1.4</version>
        </dependency>

3.1、代码生成

    @Test
    public void t4() throws IOException {
   
//定义图形验证码的长、宽、验证码字符数、干扰元素个数
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);
//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);
//图形验证码写出,可以写出到文件,也可以写出到流
        captcha.write(Files.newOutputStream(new File("d:/hutool.jpeg").toPath()));
    }

3.2、图片验证码,如下,也可细调

||||||

四、其他开源包,引入相关依赖

先引入依赖

<dependency>
            <groupId>com.github.whvcse</groupId>
            <artifactId>easy-captcha</artifactId>
            <version>1.6.2</version>
</dependency>

4.1、代码生成

 @Test
    public void t2() throws IOException {
   

        SpecCaptcha specCaptcha = new SpecCaptcha(129, 48, 4);
        // 设置字体
        specCaptcha.setFont(new Font("Times New Roman", Font.ITALIC, 34));
        // 设置类型
        specCaptcha.setCharType(Captcha.TYPE_NUM_AND_UPPER);
        specCaptcha.out(Files.newOutputStream(new File("d:/ff.jpeg").toPath()));
    }

4.2、图片验证码,如下,也可细调

||

五、关于验证码的校验逻辑,已补充

5.1、已补充,点击-博文链接