• Springboot 验证码生成图片格式和base64编码格式


    生成验证码:
    提供一个接口, 这个接口里,我们将生成的验证码存入session,然后将验证码以图片格式或者base64编码串返回给调用端。

    校验验证码:
    提供一个接口,这个接口里,我们收到调用端传过来的校验码,然后从session取出验证码,两个验证码都全部转小写,进行无大小写区分匹配校验,返回true/flase 。

    存储验证码:
    生成的验证码,在未生成图片的时候,就将4位验证码字符先存入session,以‘JCCODE’作为存取session的key。

    先创建工具类,ValidateCodeUtil.java:

    import javax.imageio.ImageIO;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.ByteArrayOutputStream;
    import java.util.Base64;
    import java.util.Random;
     
    
    public class ValidateCodeUtil {
     
     
        private static Random random = new Random();
        private int width = 165; //验证码的宽
        private int height = 45; //验证码的高
        private int lineSize = 30; //验证码中夹杂的干扰线数量
        private int randomStrNum = 4; //验证码字符个数
     
        private String randomString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ";
        private final String sessionKey = "JCCODE";
     
        //字体的设置
        private Font getFont() {
            return new Font("Times New Roman", Font.ROMAN_BASELINE, 40);
        }
     
        //颜色的设置
        private static Color getRandomColor(int fc, int bc) {
     
            fc = Math.min(fc, 255);
            bc = Math.min(bc, 255);
     
            int r = fc + random.nextInt(bc - fc - 16);
            int g = fc + random.nextInt(bc - fc - 14);
            int b = fc + random.nextInt(bc - fc - 12);
     
            return new Color(r, g, b);
        }
     
        //干扰线的绘制
        private void drawLine(Graphics g) {
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(20);
            int yl = random.nextInt(10);
            g.drawLine(x, y, x + xl, y + yl);
     
        }
     
        //随机字符的获取
        private  String getRandomString(int num){
            num = num > 0 ? num : randomString.length();
            return String.valueOf(randomString.charAt(random.nextInt(num)));
        }
     
        //字符串的绘制
        private String drawString(Graphics g, String randomStr, int i) {
            g.setFont(getFont());
            g.setColor(getRandomColor(108, 190));
            //System.out.println(random.nextInt(randomString.length()));
            String rand = getRandomString(random.nextInt(randomString.length()));
            randomStr += rand;
            g.translate(random.nextInt(3), random.nextInt(6));
            g.drawString(rand, 40 * i + 10, 25);
            return randomStr;
        }
     
     
        //生成随机图片
        public void getRandomCodeImage(HttpServletRequest request, HttpServletResponse response){
            HttpSession session = request.getSession();
            // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics g = image.getGraphics();
            g.fillRect(0, 0, width, height);
            g.setColor(getRandomColor(105, 189));
            g.setFont(getFont());
            // 干扰线
            for (int i = 0; i < lineSize; i++) {
                drawLine(g);
            }
            // 随机字符
            String randomStr = "";
            for (int i = 0; i < randomStrNum; i++) {
                randomStr = drawString(g, randomStr, i);
            }
            System.out.println("随机字符:"+randomStr);
            g.dispose();
            //移除之前的session中的验证码信息
            session.removeAttribute(sessionKey);
            //重新将验证码放入session
            session.setAttribute(sessionKey, randomStr);
            try {
                //  将图片以png格式返回,返回的是图片
                ImageIO.write(image, "PNG", response.getOutputStream());
     
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
     
     
     
     
         //生成随机图片的base64编码字符串
     
        public String getRandomCodeBase64(HttpServletRequest request, HttpServletResponse response) {
            HttpSession session = request.getSession();
            // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
            Graphics g = image.getGraphics();
            g.fillRect(0, 0, width, height);
            g.setColor(getRandomColor(105, 189));
            g.setFont(getFont());
            //干扰线
            for (int i = 0; i < lineSize; i++) {
                drawLine(g);
            }
     
            //随机字符
            String randomStr = "";
            for (int i = 0; i < randomStrNum; i++) {
                randomStr = drawString(g, randomStr, i);
            }
            System.out.println("随机字符:"+randomStr);
            g.dispose();
            session.removeAttribute(sessionKey);
            session.setAttribute(sessionKey, randomStr);
            String base64String = "";
            try {
                //  直接返回图片
                //  ImageIO.write(image, "PNG", response.getOutputStream());
                //返回 base64
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ImageIO.write(image, "PNG", bos);
     
                byte[] bytes = bos.toByteArray();
                Base64.Encoder encoder = Base64.getEncoder();
                base64String = encoder.encodeToString(bytes);
     
            } catch (Exception e) {
                e.printStackTrace();
            }
     
            return base64String;
        }
     
     
     
        }
     
     
     
     

    接下来写接口,创建一个ValidateCodeController.java,
    先是生成验证码,返回图片的接口:

    import com.example.demo.util.ValidateCodeUtil;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
     
    /**
     * @Author : JCccc
     * @CreateTime : 2019/9/25
     * @Description :
     **/
     
    @RestController
    public class ValidateCodeController {
     
     
        //返回验证码图片
       @GetMapping("/getCaptchaImg")
       public void getCaptchaImg(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
     
           try {
     
               response.setContentType("image/png");
               response.setHeader("Cache-Control", "no-cache");
               response.setHeader("Expire", "0");
               response.setHeader("Pragma", "no-cache");
               ValidateCodeUtil validateCode = new ValidateCodeUtil();
               // getRandomCodeImage方法会直接将生成的验证码图片写入response
               validateCode.getRandomCodeImage(request, response);
               // System.out.println("session里面存储的验证码为:"+session.getAttribute("JCCODE"));
     
           } catch (Exception e) {
               e.printStackTrace();
           }
     
       }
     
     
    }
     
     
     
     

    用postman来调用下接口,

    可以看到控制台的打印,这个验证码字符串已经存入了session(在后面的验证接口有介绍取值)
     

    接下来是编写一个校验验证码接口:

        //验证码校验
        @GetMapping("/checkCaptcha")
        public boolean getCheckCaptcha(@RequestParam("code") String code, HttpSession session) {
     
            try {
                //toLowerCase() 不区分大小写进行验证码校验
                String sessionCode= String.valueOf(session.getAttribute("JCCODE")).toLowerCase();
                System.out.println("session里的验证码:"+sessionCode);
                String receivedCode=code.toLowerCase();
                System.out.println("用户的验证码:"+receivedCode);
                return !sessionCode.equals("") && !receivedCode.equals("") && sessionCode.equals(receivedCode);
     
            } catch (Exception e) {
     
                return false;
            }
     
        }

    用postman调下接口,先生成验证码模拟返回给页面了,

    然后调用校验验证码接口,模拟用户在页面输入验证码,

    可以看到校验正确。

    返回base64编码串的接口:

        // 生成验证码,返回的是 base64
        @GetMapping("/getCaptchaBase64")
        public Object getCaptchaBase64(HttpServletRequest request, HttpServletResponse response) {
     
            Map result = new HashMap();
            try {
     
                response.setContentType("image/png");
                response.setHeader("Cache-Control", "no-cache");
                response.setHeader("Expire", "0");
                response.setHeader("Pragma", "no-cache");
                ValidateCodeUtil validateCode = new ValidateCodeUtil();
                // 返回base64
                String base64String = validateCode.getRandomCodeBase64(request, response);
                result.put("url", "data:image/png;base64," + base64String);
                result.put("message", "created successfull");
               //http://tool.chinaz.com/tools/imgtobase/  base64直接转为图片网站
                System.out.println("结果:" + result.get("url"));
     
            } catch (Exception e) {
                System.out.println(e);
            }
     
            return result;
        }

    用postman调用一下,


    控制台打印:


    将url取出来,

    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKUAAAAtCAIAAABAqjw4AAACjklEQVR42u3bzW7DIAwHcB57x0l7hG67TVp37juySpFQlPDxj21sKEacWrRQfhDAsBDh9H372HIcJj3+vp45eoJTmNp7r+7wq3if4d1+Yu/74w3PPugX9fY5fkpvJranKb2liq25HdjXmeWdPunXD56KzSZWHt+VlcGwHSJVjO59wO6hvhGC3uPs/gW3Ce/32zML9lGKd9a130AHvfetXMr6u3/aczfmlI3n75KoCfnhZW64BZd66AHb3lt/Tdf0fsnAyyVv8Jf28lZbxtcn76nhS96lRYPNfkzTG1+Zz6h+yRskfwVvweXVln4/f7IZL5At5t4G3jh8kwq0JEi7d8cwS0W9yYkUUHufI+TTe3fdTbl3A/L5vEox2eWSQlgNeWM33/mC3s19udn45uwRNV/mODmhAAf77H2Ow1wd/cLe+8HN2SMOMrjB4VtfnwsG2irf2ninMtsjzzPijN7ICFbwphWQ8a7HzyuBLSlv5QPQJme2ABM7YvHUjt518soaLTHLeqvFuZDhm43JaHqD5IFQD8Kxt2w4c38AijyUfzDa5DwU4GPjY7e7N3OPy4QvHYCSa4J0Bdw7zegjeJ9/jrY3EtWivcy7HocgnGTvUodjemcbxMybjGR1ewn3Zg7uBC8yvg/NG+JUyfDqMT/WZvU+J95PbXZJNW+r3pY4S3P/mN6Rdj91HHVbb06Bft7IBHrtfurV6WdBb6mVuVS8RXW95v+xV98BCnrjNyCC2k8dsN35ZrJ/7WrsbP8VeEAV9Bt6zDEnZS9bwyz59pTsh2PFW1ZY1vWwR469o/j9NU+jdSz3Xp3cvZ3cvRcmd++1yMPg/dGTbKsGq8q5ugl5sK2fqyuT29xncnXlBk/5HyEm10e/qyfBAAAAAElFTkSuQmCC

    去base64编码串转图片的网站去看看,对应的验证码图:

  • 相关阅读:
    matlab : Nelder mead simplex 单纯形直接搜索算法;
    python: 基本知识(二)
    vim: 基本知识;
    C++: 带参数回调函数和不带参数的回调函数;
    android studio DrawerLayout(官方侧滑菜单)的简单使用1
    Android studio DrawerLayout示例
    android studio ViewPager
    团队开发之任务认领
    android studio ViewPager的简单使用
    Android studio 菜单(Menu)
  • 原文地址:https://www.cnblogs.com/xiejn/p/14600341.html
Copyright © 2020-2023  润新知