• 自定义验证码 kaptcha


    <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>
    

      

    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));
    
        }
    
    
    }
    

      

    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";
        }
    }
    

      

    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";
            }
        }
    }
    

      

    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;
    
        }
    
    
    }
    

      

    <!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>
    

      

     

  • 相关阅读:
    BZOJ 2064: 分裂( 状压dp )
    BZOJ 2096: [Poi2010]Pilots( set )
    BZOJ 3444: 最后的晚餐( )
    BZOJ 3156: 防御准备( dp + 斜率优化 )
    BZOJ 1770: [Usaco2009 Nov]lights 燈( 高斯消元 )
    BZOJ 2466: [中山市选2009]树( 高斯消元 )
    BZOJ 1316: 树上的询问( 点分治 + 平衡树 )
    codevs 1074
    bzoj 1015
    bzoj 1798
  • 原文地址:https://www.cnblogs.com/rainersha/p/15638521.html
Copyright © 2020-2023  润新知