Springboot集成系统登录验证码

1 : 验证码示例

在这里插入图片描述

2 : 代码

2.1 : 对外接口 controller

VerifyController.java

package com.encrypt.common.controller;

import com.encrypt.common.service.IVerifyService;
import com.encrypt.config.bean.Result;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;

@Controller
public class VerifyController {
    
    

    @Resource
    private IVerifyService verifyService;

    //获取验证码
    @RequestMapping("/getVerifyCode")
    @ResponseBody
    public Result getVerifyCode() throws Exception{
    
    
        return verifyService.getVerifyCode();
    }

}

2.2 : 业务服务 service

IVerifyService .java

package com.encrypt.common.service;

import com.encrypt.config.bean.Result;
import java.io.IOException;

public interface IVerifyService {
    
    

    Result getVerifyCode() throws IOException;

}

VerifyServiceImpl.java

package com.encrypt.common.service.impl;

import com.encrypt.common.service.IVerifyService;
import com.encrypt.config.bean.Result;
import com.encrypt.config.utils.RedisUtil;
import com.encrypt.config.utils.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@Slf4j
public class VerifyServiceImpl implements IVerifyService {
    
    

    @Resource
    private RedisUtil redisUtil;

    /**
     * generate verification code
     */
    @Override
    public Result getVerifyCode() throws IOException {
    
    
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        log.info("The current verification code is:" + verifyCode + "\n");
        String verifyKey = UUID.randomUUID().toString();
        redisUtil.delete("verify:" + verifyKey);
        redisUtil.setEx("verify:" + verifyKey, verifyCode, 300);
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        VerifyCodeUtils.outputImage(VerifyCodeUtils.VERIFY_CODE_WIDE, VerifyCodeUtils.VERIFY_CODE_HIGH, output, verifyKey);
        String imageBase = Base64.getEncoder().encodeToString(output.toByteArray());
        Result<Map<String,Object>> result = new Result<>();
        result.setData(new HashMap<String,Object>(){
    
    {
    
    
            put("verifyKey", verifyKey);
            put("verifyIO", imageBase);
        }});
        return result;
    }

}

2.3 : 工具类 util

VerifyCodeUtils.java

package com.encrypt.config.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.Arrays;

public class VerifyCodeUtils {
    
    
    private static SecureRandom random = new SecureRandom();
    //验证码内容
    public static final String VERIFY_CODE_SOURCE = "0123456789";
    //验证码高度
    public static final int VERIFY_CODE_HIGH = 38;
    //验证码宽度
    public static final int VERIFY_CODE_WIDE = 99;
    //验证码存入session中的Key
    public static final String VERIFY_CODE = "verify_code";

    /**
     * 使用系统默认字符源生成验证码
     * @param verifySize 验证码长度
     */
    public static String generateVerifyCode(int verifySize) {
    
    
        return generateVerifyCode(verifySize, VERIFY_CODE_SOURCE);
    }

    /**
     * 使用指定源生成验证码
     * @param verifySize 验证码长度
     * @param sources 验证码字符源
     */
    public static String generateVerifyCode(int verifySize, String sources) {
    
    
        if (sources == null || sources.length() == 0) sources = VERIFY_CODE_SOURCE;
        SecureRandom rand = new SecureRandom();
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for (int i = 0; i < verifySize; i++) {
    
    
            verifyCode.append(sources.charAt(rand.nextInt(sources.length() - 1)));
        }
        return verifyCode.toString();
    }

    /**
     * 输出指定验证码图片流
     */
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
    
    
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        SecureRandom rand = new SecureRandom();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[] {
    
     Color.BLACK, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA,
                Color.ORANGE, Color.PINK, Color.YELLOW };
        float[] fractions = new float[colors.length];
        for (int i = 0; i < colors.length; i++) {
    
    
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
        g2.setColor(Color.WHITE);// 设置边框色
        g2.fillRect(0, 0, w, h);
        Color c = getRandColor(150, 250);
        g2.setColor(c);// 设置背景色
//		g2.fillRect(0, 2, w, h - 4);
        // 绘制干扰线
        SecureRandom random = new SecureRandom();
        g2.setColor(getRandColor(160, 200));// 设置线条的颜色
        for (int i = 0; i < 20; i++) {
    
    
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }
        //添加噪点
//        float yawpRate = 0.05f;// 噪声率
        BigDecimal yawpRate = new BigDecimal(0.05);
        BigDecimal w1 = new BigDecimal(w);
        BigDecimal h1 = new BigDecimal(h);
        int area = yawpRate.multiply(w1).multiply(h1).intValue();
        for (int i = 0; i < area; i++) {
    
    
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
//		shear(g2, w, h, c);// 使图片扭曲
        g2.setColor(getRandColor(100, 160));
        int fontSize = h - 6;
        Font font = new Font("Bitstream Charter", Font.BOLD, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        AffineTransform affine = null;
        for (int i = 0; i < verifySize; i++) {
    
    
            affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1),
                    (w / verifySize) * i + fontSize / 2, h / 2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
        }
        g2.dispose();
        ImageIO.write(image, "jpg", os);
    }

    private static Color getRandColor(int fc, int bc) {
    
    
        if (fc > 255){
    
    
            fc = 255;}
        if (bc > 255){
    
    
            bc = 255;}
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    private static int getRandomIntColor() {
    
    
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
    
    
            color = color << 8;
            color = color | c;
        }
        return color;
    }

    private static int[] getRandomRgb() {
    
    
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
    
    
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }

}

猜你喜欢

转载自blog.csdn.net/qq_38254635/article/details/129735679