学习了Java两个月后,自己开始跟着老师做了一个小项目,我想记录一下自己第一次做项目的过程,以及自己遇到的一些难题。

老师已经把整个项目给我们讲解完了,但是你懂的,不经过自己的实际操作,你是很难从项目中学到东西的。于是我开始从前端页面开始写,按照自己的理解和参照老师的代码,我成功把注册和登录页面写出来了(哈哈,我的基础的的确很差),而且实现了第一个难题的突破,也就是验证码这个部分,如下图:

spring boot spring security 添加验证码 springboot 登录验证码_验证码

(先忽略我这个后端仔写的页面~~~)

看,这个验证码还不错吧,只要点击它,就可以实时刷新啦。因为前端用的是Vue.js、ElementUI、还有Axios写的,所以把验证码传到页面还算简单,真正的难点是画验证码的部分。你没听错,这个验证码是画出来的,代码真的很神奇。我把验证码的实现封装在了一个工具类中,话不多说,直接上代码:

话不多说,直接上代码,

/**
 * 验证码工具类
 */
public final class VerifyCodeUtil {
    /*定义图片的width*/
    private static int WIDTH = 80;
    /*定义图片的height*/
    private static int HEIGHT = 30;
    /*定义图片上显示的验证码个数*/
    private static int CODECOUNT = 4;
    /*字符间隔*/
    private static final int CHARACETRSPACING = 8;
    /*字体大小*/
    private static final int FONTHEIGHT = 24;
    /*干扰线*/
    private static final int LINENUMBER = 25;
    /*字符垂直位置*/
    private static final int VERTICALPOSITION = 24;
    private static final char[] CODESEQUENCE = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
            'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n',
            'o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0'};
    /*无参构造器*/
    private VerifyCodeUtil(){}

    /**
     * 生成验证码字符串
     * @param count 验证码字符个数
     * @return 返回验证码字符串
     */
    public static String generateVerifyCode(int count){
        //产生随机数
        Random random = new Random();
        //生成验证码
        StringBuilder randomCode = new StringBuilder();/*StringBuilder可变字符串序列*/
        for (int i = 0; i < count; i++) {
            //获取一位验证码
            String code = String.valueOf(CODESEQUENCE[random.nextInt(CODESEQUENCE.length)]);
            randomCode.append(code);/*字符串拼接*/
        }
        return randomCode.toString();
    }

    /**
     * 生成验证码字符串
     * @return 返回验证码字符串
     */
    public static String generateVerifyCode(){//方法的重载
        return generateVerifyCode(CODECOUNT);//静态方法中只能调用静态方法
    }

    /**
     * 生成验证码图片
     * @param width 验证码图片的宽度,默认95
     * @param  height 验证码图片的高度,默认30
     * @param code 验证码字符串
     * @return 返回创建好的画布对象
     */
    public static BufferedImage outputImage(Integer width, Integer height, String code){
        if(!ObjectUtil.isEmpty(width)){//Spring工具包中的方法
            WIDTH = width;//为图片设置宽度
        }
        if(!ObjectUtil.isEmpty(height)){
            HEIGHT = height;//为图片设置高度
        }
        if(ObjectUtil.isEmpty(code)){
            return null;//做这些判断都是为了防止出现空指针异常
        }
        //创建画布对象(不带透明色)
        BufferedImage buffImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        //创建画笔对象
        Graphics gd = buffImg.getGraphics();
        //创建生成随机数对象
        Random random = new Random();
        //设置画布背景色(白色)
        gd.setColor(Color.WHITE);
        //根据设置的背景色填充画布
        gd.fillRect(0, 0, WIDTH, HEIGHT);
        //创建字体对象
        Font font = new Font("Arial", Font.BOLD, FONTHEIGHT);
        //给画笔对象设置字体
        gd.setFont(font);
        //给画笔对象设置颜色
        gd.setColor(Color.BLACK);
        //给画布绘制边框
        gd.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
        //生成验证码
        char[] codes = code.toCharArray();
        for (int i = 0; i < codes.length; i++) {
            //设置颜色
            gd.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            //绘制验证码
            gd.drawString(String.valueOf(codes[i]), CHARACETRSPACING + i * 2 * CHARACETRSPACING, VERTICALPOSITION);
        }
        //设置干扰线颜色(深灰色)
        gd.setColor(Color.DARK_GRAY);
        //干扰线
        for (int i = 0; i < LINENUMBER; i++) {
            //线的起始X坐标
            int startX = random.nextInt(WIDTH);
            //线的起始Y坐标
            int startY = random.nextInt(HEIGHT);
            //线的结束X坐标
            int endX = random.nextInt(VERTICALPOSITION);
            //线的结束Y坐标
            int endY = random.nextInt(VERTICALPOSITION);
            //绘制直线
            gd.drawLine(startX, startY, startX + endX, startY + endY);
        }
        return buffImg;
    }
    /**
     * 输出验证码图片流
     * @param w 宽度
     * @param h 高度
     * @param code 验证码字符串
     * @param os 输出流
     */
    public static void outputImage(Integer w, Integer h, String code, OutputStream os) throws IOException {
        if(ObjectUtil.isEmpty(code)){
            return;
        }
        // 创建画布对象
        BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        // 创建画笔对象
        Graphics gd = bi.getGraphics();
        // 创建生成随机数对象
        Random random = new Random();
        // 设置画布背景色
        gd.setColor(Color.DARK_GRAY);
        // 根据设置的背景色填充画布
        gd.fillRect(0, 0, WIDTH, HEIGHT);
        // 创建字体对象
        Font font = new Font("Arial", Font.BOLD, FONTHEIGHT);
        // 给画笔对象设置字体
        gd.setFont(font);
        // 给画笔设置颜色
        gd.setColor(Color.BLACK);
        // 给画布绘制边框
        //gd.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
        // 设置干扰线颜色
        gd.setColor(Color.BLACK);
        // 干扰线
        for (int i = 0; i < LINENUMBER; i++) {
            // 线的起始X坐标
            int startX = random.nextInt(WIDTH);
            // 线的起始Y坐标
            int startY = random.nextInt(HEIGHT);
            // 线的结束X坐标
            int endX = random.nextInt(VERTICALPOSITION);
            // 线的结束Y坐标
            int endY = random.nextInt(VERTICALPOSITION);
            // 绘制直线
            gd.drawLine(startX, startY, startX + endX, startY + endY);
        }
        // 生成验证码
        char[] codes = code.toCharArray();
        for (int i = 0; i < codes.length; i++) {
            // 设置颜色
            gd.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            // 绘制验证码
            gd.drawString(String.valueOf(codes[i]), CHARACETRSPACING + i * 2 * CHARACETRSPACING, VERTICALPOSITION);
        }
        gd.dispose();
        ImageIO.write(bi, "png", os);
    }
    /**
     * 输出验证码图片流
     * @param code 验证码
     * @param os 创建的输出流
     */
    public static void outputImage(String code, OutputStream os) throws IOException {
        outputImage(WIDTH, HEIGHT, code, os);
    }
}

这就是实现验证码的整个过程啦。我们做的是一个简单的客户管理系统,后续还会继续更新嗷~