JAVA如何生成kaptcha验证码呢?

欣喜 Java经验 发布时间:2024-01-30 16:24:21 阅读数:12952 1
下文笔者讲述生成字母验证码和算术验证码的方法及示例分享,如下所示
生成字母验证码和算术验证码的实现思路
       1.引入相应的依赖com.github.penggle.kaptcha
       2.生成 new DefaultKaptcha()实例
          放入相应的配置即可生成kaptcha验证码
例:java代码生成kaptcha验证码的示例

引入maven

<!--图片验证码-->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>javax.servlet-api</artifactId>
                    <groupId>javax.servlet</groupId>
                </exclusion>
            </exclusions>
        </dependency>
 

验证码配置类

KaptchaConfig.java
 
import com.google.code.kaptcha.impl.DefaultKaptcha;
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(name = "captchaProducer")
    public DefaultKaptcha getKaptchaBean() {
        Properties properties = new Properties();
        //图片边框
        properties.setProperty("kaptcha.border", "no");
        //文本集合,验证码值从此集合中获取
        properties.setProperty("kaptcha.textproducer.char.string", "ABCDEGHJKLMNRSTUWXY23456789");
        //字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "0,84,144");
        //干扰颜色
        properties.setProperty("kaptcha.noise.color", "0,84,144");
        //字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        //背景颜色渐变,开始颜色
        properties.setProperty("kaptcha.background.clear.from", "247,255,234");
        //背景颜色渐变,结束颜色
        properties.setProperty("kaptcha.background.clear.to", "247,255,234");
        //图片宽
        properties.setProperty("kaptcha.image.width", "125");
        //图片高
        properties.setProperty("kaptcha.image.height", "35");
        properties.setProperty("kaptcha.session.key", "code");
        //验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        //字体
        properties.setProperty("kaptcha.textproducer.font.names", "Arial, Courier");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

控制器类--验证码应用

KaptchaController.java    

import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@RestController
public class KaptchaController {

    /**
     * 加载图形验证码
     */
    @GetMapping("/kaptcha")
    public String getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setDateHeader("Expires", 0);
        // 设置浏览器渲染不做本地缓存
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Content-Security-Policy", "none");
        // 设置浏览器渲染不读取浏览器缓存
        response.setHeader("Pragma", "no-cache");

        String originHeader = request.getHeader("Origin");
        // 这个限定来自自身服务端域名
        /*if (originHeader != null && (originHeader.contains(request.getServerName()))) {
            response.setHeader("Access-Control-Allow-Origin", originHeader);
        } else {
            response.setHeader("Access-Control-Allow-Origin", request.getServerName());
        }*/
        // 设置浏览器渲染图片类型
        response.setContentType("image/jpeg");
        // 生成验证码内容
        String capText = captchaProducer.createText();

        String uuid= UUID.randomUUID().toString().toLowerCase();


        /**
         *这里将uuid作为key存入redis中,用于后面的验证码验证,可以设置失效时间 
         */

        //redisService.set(uuid, capText);

        //生成图片
        BufferedImage bi = captchaProducer.createImage(capText);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bi, "jpg", outputStream);

        Map<String, Object> map = new HashMap<String, Object>(2);

        //转为base64
        String img=imageToBase64ByByte(outputStream.toByteArray());

        map.put("img", img);
        //uuid 主要用于验证验证码使用
        map.put("uuid", uuid);

        try {
            outputStream.flush();
        }finally {
            outputStream.close();
        }
        //这里将map返回到前台,此处简单demo
        return img+","+uuid;
    }


    public static String imageToBase64ByByte(byte[] data) {
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);
    }


    /**
     * 验证验证码是否正确
     * @param code  前台填写的验证码
     * @param uuid  生成验证码时返回的uuid
     * @return
     */
    @GetMapping("/valid")
    public Boolean valid(String code,String uuid) {

        String verifyCode ="这里从redis中取出原本的验证码进行判断:redisService.get(uuid)";
        System.out.println(verifyCode);
        return verifyCode.equalsIgnoreCase(code);
    }


    @Autowired
    private Producer captchaProducer;


}
 

算术验证码示例

MathKaptchaTextCreator.java

import com.google.code.kaptcha.text.impl.DefaultTextCreator;

import java.security.SecureRandom;
import java.util.Random;
/**
 * 算术数字验证码文本生成器
 */
public class MathKaptchaTextCreator extends DefaultTextCreator
{
    private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");

    @Override
    public String getText()
    {
        Integer result = 0;
        Random random = new SecureRandom();
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        StringBuilder suChinese = new StringBuilder();
        int randomoperands = (int) Math.round(Math.random() * 2);
        if (randomoperands == 0)
        {
            result = x * y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("*");
            suChinese.append(CNUMBERS[y]);
        }
        else if (randomoperands == 1)
        {
            if (!(x == 0) && y % x == 0)
            {
                result = y / x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("/");
                suChinese.append(CNUMBERS[x]);
            }
            else
            {
                result = x + y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("+");
                suChinese.append(CNUMBERS[y]);
            }
        }
        else if (randomoperands == 2)
        {
            if (x >= y)
            {
                result = x - y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[y]);
            }
            else
            {
                result = y - x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[x]);
            }
        }
        else
        {
            result = x + y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("+");
            suChinese.append(CNUMBERS[y]);
        }
        suChinese.append("=?@" + result);
        return suChinese.toString();
    }
}

KaptchaConfig.java

    @Bean(name = "mathCaptchaProducer")
    public DefaultKaptcha getmathCaptchaBean() {
        Properties properties = new Properties();
        //图片边框
        properties.setProperty("kaptcha.border", "no");
        //文本集合,验证码值从此集合中获取
        properties.setProperty("kaptcha.textproducer.char.string", "ABCDEGHJKLMNRSTUWXY23456789");
        //字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "0,84,144");
        //干扰颜色
        properties.setProperty("kaptcha.noise.color", "0,84,144");
        //字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "30");
        //背景颜色渐变,开始颜色
        properties.setProperty("kaptcha.background.clear.from", "247,255,234");
        //背景颜色渐变,结束颜色
        properties.setProperty("kaptcha.background.clear.to", "247,255,234");
        //图片宽
        properties.setProperty("kaptcha.image.width", "125");
        //图片高
        properties.setProperty("kaptcha.image.height", "35");
        properties.setProperty("kaptcha.session.key", "code");
        // 验证码文本生成器(根据自己的包路径来填写)
        properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.example.kaptcha.config.MathKaptchaTextCreator");

        //验证码长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        //字体
        properties.setProperty("kaptcha.textproducer.font.names", "Arial, Courier");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }

控制器-算术验证码

import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import com.google.code.kaptcha.Producer;

/**
 *  算术形式图片验证码
 */
@Controller
public class MathCaptchaController {


    @Resource(name = "mathCaptchaProducer")
    private Producer captchaProducerMath;

    /**
     * 验证码生成
     */
    @GetMapping(value = "/mathKaptcha")
    public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) {
        ServletOutputStream out = null;
        try {
            HttpSession session = request.getSession();
            response.setDateHeader("Expires", 0);
            response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            response.addHeader("Cache-Control", "post-check=0, pre-check=0");
            response.setHeader("Pragma", "no-cache");
            response.setContentType("image/jpeg");

            String capText = captchaProducerMath.createText();
            String capStr = capText.substring(0, capText.lastIndexOf("@"));
            //code 就是算术的结果 也就是输入的验证码
            String code = capText.substring(capText.lastIndexOf("@") + 1);
            BufferedImage bi = captchaProducerMath.createImage(capStr);

            /**
             *这里将uuid作为key存入redis中,用于后面的验证码验证,可以设置失效时间
             * springboot整合redis可以参考 https://www.cnblogs.com/pxblog/p/12980634.html
             */

            //redisService.set(uuid, code);

            out = response.getOutputStream();
            ImageIO.write(bi, "jpg", out);
            out.flush();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

页面调用

<div class="letter pointer" 
    id="getCapatchImg"><img id="capatchImg" 
   onclick="genCapatch()" /></div>
 
// 图形验证码

            var uuid="";
            $(function () {
                $("#getCapatchImg").on("click", function (event) {
                            genCapatch();
                    });
            });
            function genCapatch() {
                    $.ajax({
                            url: "/kaptcha",
                            data: {},
                            success: function (result) {
                                    document.getElementById('capatchImg').src = "data:image/png;base64," + result.data.img;
                                    uuid=result.data.uuid
                            }
                    });
            }
 
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaJingYan/202401/17066031327860.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者