自定义验证码 - kaptcha

1
2
3
4
5
6
7
8
9
10
11
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.6.0</version>
        </dependency>
 
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package org.example.captcha;
 
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
 
/**
 * @author banjuan
 * @date 2021/11/30 2:48 下午
 */
public class CodeUtil {
 
    /**
     * 将获取到的前端参数转为string类型
     * @param request
     * @param key
     * @return
     */
    public static String getString(HttpServletRequest request, String key) {
        try {
            String result = request.getParameter(key);
            if(result != null) {
                result = result.trim();
            }
            if("".equals(result)) {
                result = null;
            }
            return result;
        }catch(Exception e) {
            return null;
        }
    }
 
    /**
     * 验证码校验
     * @param request
     * @return
     */
    public static boolean checkVerifyCode(HttpServletRequest request) {
        //获取生成的验证码
        String verifyCodeExpected = (String) request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
        //获取用户输入的验证码
        String verifyCodeActual = CodeUtil.getString(request, "verifyCodeActual");
        if (null != verifyCodeActual) {
            verifyCodeActual = verifyCodeActual.toLowerCase();
        }
        if(verifyCodeActual == null ||!verifyCodeActual.equals(verifyCodeExpected)) {
            return false;
        }
        return true;
    }
 
    /**
     * 宽高可作为参数传入
     */
    private static final int WIDTH = 110;
    private static final int HEIGHT = 40;
 
    /**
     * 传入BufferedImage对象,并将生成好的验证码保存到BufferedImage中
     * @param bufferedImage
     * @return
     */
    public static String drawRandomText(BufferedImage bufferedImage) {
        Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
        // 设置画笔颜色-验证码背景色
        graphics.setColor(Color.WHITE);
        // 填充背景
        graphics.fillRect(0, 0, WIDTH, HEIGHT);
        graphics.setFont(new Font("宋体,楷体,微软雅黑", Font.BOLD, 26));
 
        // 数字和字母的组合
        String baseNumLetter = "123456789abcdefghijkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";
 
        StringBuilder builder = new StringBuilder();
        // 旋转原点的 x 坐标
        int x = 8;
        String ch;
        Random random = new Random();
 
        for (int i = 0; i < 4; i++) {
            graphics.setColor(getRandomColor());
 
            //设置字体旋转角度,角度小于30度
            int degree = random.nextInt() % 30;
            int dot = random.nextInt(baseNumLetter.length());
 
            ch = baseNumLetter.charAt(dot) + "";
            builder.append(ch);
 
            //正向旋转
            graphics.rotate(degree * Math.PI / 180, x, 24);
            graphics.drawString(ch, x, 24);
 
            //反向旋转
            graphics.rotate(-degree * Math.PI / 180, x, 24);
            x += 24;
        }
 
        //画干扰线
        for (int i = 0; i < 6; i++) {
            // 设置随机颜色
            graphics.setColor(getRandomColor());
 
            // 随机画线
            graphics.drawLine(random.nextInt(WIDTH), random.nextInt(HEIGHT),
                    random.nextInt(WIDTH), random.nextInt(HEIGHT));
 
        }
 
        //添加噪点
        for (int i = 0; i < 30; i++) {
            int x1 = random.nextInt(WIDTH);
            int y1 = random.nextInt(HEIGHT);
 
            graphics.setColor(getRandomColor());
            graphics.fillRect(x1, y1, 2, 2);
        }
        return builder.toString();
    }
 
    /**
     * 随机取色
     */
    private static Color getRandomColor() {
        Random ran = new Random();
        return new Color(ran.nextInt(256),
                ran.nextInt(256), ran.nextInt(256));
 
    }
 
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package org.example.captcha;
 
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
 
/**
 * @author banjuan
 * @date 2021/11/30 2:45 下午
 */
@Controller
public class CodeController {
    @Autowired
    private Producer captchaProducer = null;
    @RequestMapping("/kaptcha")
    public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        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 = captchaProducer.createText();
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        //向客户端写出
        BufferedImage bi = captchaProducer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
 
    @RequestMapping("/verification")
    public void createImageCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        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");
        //设置响应格式为png图片
        response.setContentType("image/png");
        // 生成图片验证码
        BufferedImage image = new BufferedImage(110, 40, BufferedImage.TYPE_INT_RGB);
        String randomText = CodeUtil.drawRandomText(image);
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, randomText.toLowerCase());
        System.out.println("验证码->>>"+randomText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "png", out);
        out.flush();
        out.close();
    }
 
 
    @RequestMapping("/hellow")
    public String Hello() {
        return "hello";
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package org.example.captcha;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import javax.servlet.http.HttpServletRequest;
 
/**
 * @author banjuan
 * @date 2021/11/30 2:59 下午
 */
@RestController
public class HelloWorld {
    @RequestMapping("/hello")
    public String hello(HttpServletRequest request) {
        if (!CodeUtil.checkVerifyCode(request)) {
            return "验证码有误!";
        } else {
            return "hello,world";
        }
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package org.example.captcha;
 
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;
 
/**
 * @author banjuan
 * @date 2021/11/30 3:01 下午
 */
@Configuration
public class KaptchaConfig {
    @Bean
    public DefaultKaptcha getDefaultKaptcha(){
//        DefaultKaptcha captchaProducer = new DefaultKaptcha();
//        Properties properties = new Properties();
//        properties.setProperty("kaptcha.border", "no");
//        //properties.setProperty("kaptcha.border.color", "105,179,90");
//        properties.setProperty("kaptcha.textproducer.font.color", "black");
//        properties.setProperty("kaptcha.image.width", "110");
//        properties.setProperty("kaptcha.image.height", "40");
//        properties.setProperty("kaptcha.textproducer.font.size", "24");
//        properties.setProperty("kaptcha.session.key", "code");
//        properties.setProperty("kaptcha.noise.color", "white");
//        properties.setProperty("kaptcha.textproducer.char.space", "4");
//        properties.setProperty("kaptcha.obscurificator.impl", "com.google.code.kaptcha.impl.FishEyeGimpy");
////        properties.setProperty("kaptcha.background.clear.from", "0,255,0");
////        properties.setProperty("kaptcha.background.clear.to", "255,255,0");
//        properties.setProperty("kaptcha.textproducer.char.length", "4");
////        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
//        properties.setProperty("kaptcha.textproducer.font.names", "Algerian");
//        Config config = new Config(properties);
//        captchaProducer.setConfig(config);
//        return captchaProducer;
 
 
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 图片边框
        properties.setProperty("kaptcha.border", "no");
        // 边框颜色
        //properties.setProperty("kaptcha.border.color", "105,179,90");
        // 字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "red");
        // 验证码整体宽度
        properties.setProperty("kaptcha.image.width", "110");
        // 验证码整体高度
        properties.setProperty("kaptcha.image.height", "40");
        // 文字个数
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        // 文字大小
        properties.setProperty("kaptcha.textproducer.font.size","24");
        // 文字随机字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        // 文字距离
        properties.setProperty("kaptcha.textproducer.char.space","4");
        // 干扰线颜色
        properties.setProperty("kaptcha.noise.color","blue");
        // 自定义验证码背景
        //properties.setProperty("kaptcha.background.impl","com.dt.springbootdemo.config.kaptcha.NoKaptchaBackhround");
        Config config=new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
 
    }
 
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript">
        function refresh() {
            document.getElementById('captcha_img').src="/verification?"+Math.random();
        }
    </script>
</head>
<body>
<form action="/hello" method="post">
    验证码:  <input type="text" placeholder="请输入验证码" name="verifyCodeActual">
    <div class="item-input">
        <img id="captcha_img" alt="点击更换" title="点击更换"
             onclick="refresh()" src="/verification" />
    </div>
    <input type="submit" value="提交" />
</form>
 
</body>
</html>

  

 

 

 

posted @   刘维风  阅读(311)  评论(0编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· DeepSeek火爆全网,官网宕机?本地部署一个随便玩「LLM探索」
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 上周热点回顾(1.20-1.26)
· 【译】.NET 升级助手现在支持升级到集中式包管理
点击右上角即可分享
微信分享提示