JAVA中验证码工具类的封装

1. 方案一

Java内部方法生成,不需要其它依赖

样式如图所示:

package com.hyh.ad.common.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Random;

/**
 * 生成验证码工具类
 */
public class CheckCodeUtil {

    public static final String VERIFY_CODES = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static Random random = new Random();




    /**
     * 输出随机验证码图片流,并返回验证码值(一般传入输出流,响应response页面端,Web项目用的较多)
     *
     * @param w
     * @param h
     * @param os
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, os, verifyCode);
        return verifyCode;
    }

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

    /**
     * 使用指定源生成验证码
     *
     * @param verifySize 验证码长度
     * @param sources    验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String sources) {
        // 未设定展示源的字码,赋默认值大写字母+数字
        if (sources == null || sources.length() == 0) {
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for (int i = 0; i < verifySize; i++) {
            verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
        }
        return verifyCode.toString();
    }

    /**
     * 生成随机验证码文件,并返回验证码值 (生成图片形式,用的较少)
     *
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }



    /**
     * 生成指定验证码图像文件
     *
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, String code) throws IOException {
        if (outputFile == null) {
            return;
        }
        File dir = outputFile.getParentFile();
        //文件不存在
        if (!dir.exists()) {
            //创建
            dir.mkdirs();
        }
        try {
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * 输出指定验证码图片流
     *
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    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);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 创建颜色集合,使用java.awt包下的类
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[]{Color.WHITE, 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.GRAY);
        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);
        // 设置背景色
        g2.setColor(c);
        g2.fillRect(0, 2, w, h - 4);

        // 绘制干扰线
        Random random = new Random();
        // 设置线条的颜色
        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;
        int area = (int) (yawpRate * w * h);
        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 - 4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for (int i = 0; i < verifySize; i++) {
            AffineTransform 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);
    }

    /**
     * 随机颜色
     *
     * @param fc
     * @param bc
     * @return
     */
    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;
    }

    private static void shear(Graphics g, int w1, int h1, Color color) {
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }

    private static void shearX(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(2);

        boolean borderGap = true;
        int frames = 1;
        int phase = random.nextInt(2);

        for (int i = 0; i < h1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(0, i, w1, 1, (int) d, 0);
            if (borderGap) {
                g.setColor(color);
                g.drawLine((int) d, i, 0, i);
                g.drawLine((int) d + w1, i, w1, i);
            }
        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(40) + 10; // 50;

        boolean borderGap = true;
        int frames = 20;
        int phase = 7;
        for (int i = 0; i < w1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(i, 0, 1, h1, 0, (int) d);
            if (borderGap) {
                g.setColor(color);
                g.drawLine(i, (int) d, i, 0);
                g.drawLine(i, (int) d + h1, i, h1);
            }
        }
    }
}

下面是一个Controller来使用这个工具类

    /**
     * 验证码
     * @param response
     */
    @GetMapping("/generate")
    public void generateCaptcha(HttpServletResponse response, HttpServletRequest request) throws IOException {
        response.setContentType("image/jpeg");
        OutputStream fos = response.getOutputStream();
        String checkCode = CheckCodeUtil.outputVerifyImage(100, 50, fos, 4);
        log.info("验证码:{}", checkCode);
        //验证码存到redis
        cacheClient.setObject(RedisConstant.CAPTCHA_PREFIX, checkCode,             
        RedisConstant.TIMEOUT_FIVE, TimeUnit.MINUTES);
    }

2. 方案二

这是用 kaptch包来进行验证码的生成的

样式如下:

2.1 导入依赖

        <!-- 验证码 -->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>

2.2 基础配置

验证码文本生成器

package com.hyh.admin.config;

import com.google.code.kaptcha.text.impl.DefaultTextCreator;

import java.util.Random;

/**
 * 验证码文本生成器
 * 
 * @author pd
 */
public class KaptchaTextCreator extends DefaultTextCreator
{
    private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");

    @Override
    public String getText()
    {
        Integer result = 0;
        Random random = new Random();
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        StringBuilder suChinese = new StringBuilder();
        int randomoperands = (int) Math.round(Math.random() * 2);
        if (randomoperands == 0)
        {
            result = x * y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("*");
            suChinese.append(CNUMBERS[y]);
        }
        else if (randomoperands == 1)
        {
            if (!(x == 0) && y % x == 0)
            {
                result = y / x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("/");
                suChinese.append(CNUMBERS[x]);
            }
            else
            {
                result = x + y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("+");
                suChinese.append(CNUMBERS[y]);
            }
        }
        else if (randomoperands == 2)
        {
            if (x >= y)
            {
                result = x - y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[y]);
            }
            else
            {
                result = y - x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[x]);
            }
        }
        else
        {
            result = x + y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("+");
            suChinese.append(CNUMBERS[y]);
        }
        suChinese.append("=?@" + result);
        return suChinese.toString();
    }
}
package com.hyh.admin.config;

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;

import static com.google.code.kaptcha.Constants.*;

/**
 * 验证码配置
 * 
 * @author pd
 */
@Configuration
public class CaptchaConfig
{
    @Bean(name = "captchaProducer")
    public DefaultKaptcha getKaptchaBean()
    {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 是否有边框 默认为true 我们可以自己设置yes,no
        properties.setProperty(KAPTCHA_BORDER, "yes");
        // 验证码文本字符颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
        // 验证码图片宽度 默认为200
        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
        // 验证码图片高度 默认为50
        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
        // 验证码文本字符大小 默认为40
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
        // KAPTCHA_SESSION_KEY
        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
        // 验证码文本字符长度 默认为5
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }

    @Bean(name = "captchaProducerMath")
    public DefaultKaptcha getKaptchaBeanMath()
    {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 是否有边框 默认为true 我们可以自己设置yes,no
        properties.setProperty(KAPTCHA_BORDER, "yes");
        // 边框颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
        // 验证码文本字符颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
        // 验证码图片宽度 默认为200
        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
        // 验证码图片高度 默认为50
        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
        // 验证码文本字符大小 默认为40
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
        // KAPTCHA_SESSION_KEY
        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
        // 验证码文本生成器
        properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.hyh.admin.config.KaptchaTextCreator");//这里对应自己上面文本生成器的路径
        // 验证码文本字符间距 默认为2
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
        // 验证码文本字符长度 默认为5
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
        // 验证码噪点颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
        // 干扰实现类
        properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

这里依旧使用一个controller来展示

在application.yaml配置

ad:
 # 验证码类型 math 数组计算 char 字符验证
   captchaType: math
package com.hyh.admin.sys.controller.captcha;


import cn.hutool.core.codec.Base64;
import com.google.code.kaptcha.Producer;
import com.hyh.ad.common.constants.Constants;
import com.hyh.ad.common.core.domain.AjaxResult;
import com.hyh.ad.common.core.redis.CacheClient;
import com.hyh.ad.common.utils.uuid.IdUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 验证码操作处理
 * 
 * @author pd
 */
@RestController
public class CaptchaController
{
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;

    @Autowired
    private CacheClient cacheClient;
    
    // 验证码类型
    @Value("${ad.captchaType}")
    private String captchaType;

    /**
     * 生成验证码
     */
    @GetMapping("/captchaImage")
    @ApiOperation("生成验证码 返回uuid和图片base64编码")
    public AjaxResult getCode(HttpServletResponse response) throws IOException
    {
        // 保存验证码信息
        String uuid = IdUtils.simpleUUID();
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;

        String capStr = null, code = null;
        BufferedImage image = null;

        // 生成验证码
        if ("math".equals(captchaType))
        {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }

        cacheClient.setObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            return AjaxResult.error(e.getMessage());
        }

        AjaxResult ajax = AjaxResult.success();
        ajax.put("uuid", uuid);
        ajax.put("img", Base64.encode(os.toByteArray()));
        return ajax;
    }
}

我们访问一下这个接口

 把img复制到img标签下 前面需要加上data:image/gif;base64 以为是base64加密的

<img src="data:image/gif;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAA8AKADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtrW1ga1hZoIySikkoOeKsCztv+feL/vgU2z/484P+ua/yqyKiMY8q0IjGPKtCIWdr/wA+0P8A3wKeLK1/59of+/YqUU7IHWnyx7D5Y9iIWVp/z6w/9+xThY2n/PrB/wB+xWd/wlGhrf8A2JtUtVuAcbDIBz6Z6ZrZUg9KudBwtzRtfyDli+hELCz/AOfWD/v2KcLCz/59IP8Av2KmFPBFRyx7Byx7EI0+y/59Lf8A79j/AApw06y/587f/v0v+FTiqGsa5YaBp0l9qE/lQJgZwSSTwAAOpqoUueSjCN2+lg5YroWxp1j/AM+dv/36X/CnDTbH/nyt/wDv0v8AhVTQtbtdf0qHUbRZVgm3bPNUKxAJGcZ9Qa1RROlyScZKzQcsX0K40yw/58rb/v0v+FPGmWH/AD423/fpf8KsDisrVvFOi6E6JqWoQ27vyqscnHrgc06dB1JcsI3fkrg4xW6L40vT/wDnxtv+/K/4U8aVp/8Az4Wv/flf8Kj03VrDVrYXFhdw3MJ/jicMB7H0PtV8VMqai7Nahyx7FYaVp3/Pha/9+V/wpw0nTv8AoH2v/flf8KtCnilyx7Byx7FUaTpv/QPtP+/K/wCFVtT0vT49IvXSxtVdYHKsIVBB2nkcVrCqurf8gW//AOveT/0E0pRjyvQUox5XoclZ/wDHnB/1zX+VWRVez/484P8Armv8qsinH4UOPwoUVzvjLUJ7Lw5fPbEiYRHaR19/0ro8cVgeIrVp7V1xkEYIrWlNQmpNXsxvY8O0PTLTVI7j7TLIswI2sp6E9z613vw98V3VnqR8O6pKX2nEDscn6fl0rj7zSrvRL1ruzXfED88XoP8ACse41OaXVF1KFTFIhVgQc4I6V984PN3UtJSpSV47XhLTS2+v3M5b+zt3Ppa81CG0tzNLKkaDqzNgD8a8s+GGqSDxRq8Uty7rICyqXJX7/JH5is/XbQeKzbaqb2VIGgX9xy21uc45wP8A61cdcW8ul6nH9muJITkbJtxUqfqK8fLMHhqlKphXU/eTW3K/dcXe1+r9DScpJqVtD6cvNQgsbCW7ncJFEhd29AOteAeOfFV14puRNGrx6XC5SFW/ibHLGuj0PW/E1xK2k65E11YTxNH5wQHGR3ZexGRzzzWZ4l0Ipp/k20ISOL5kVR3H9TzWWXToZZi4+1tNtq0k7xSejfr+SHO846G/4Z+IFj4b0DR7a9gmMEkRHmxAHaQ2DkV6ZpfirQ9XgEtlqdtKCM43hWH1U4I/EV886HqcSaPcW1zZx3iQHzBG45CH7xX0wefxpGsvDV8fMt76Wyz1ikG4D6Z/xNdGKyqg6tRVFOLUn7yXMnd3V0tVo15CjN2Vj6L/AOEh0u4u5LK1v7ee6RDI8cUgYquQOcdOorxvWPCU174hm1DVb77QJXLMiKRgdgD6VX8M6t4V8L6lG8M9zc3M2IZJzxHGpIySOOOAe/SvXJtGimQyMBXmVXXyupfDOUVJbuNm+9r3a/MtWmtTxm6t7zwbOur6DeSpGGAkic579D6ivb/BPiqPxToMV8FCSgmOVPRgBn+YrwHxnqd22s3WmMvlxRSbdo/i9D/WvU/hVaPp2jLC3DSMZGHuf/1V6Oa05f2bSrYpp1ZPRrdxt172Ipv32o7Hqop4pifdFSCvlTccKq6t/wAgS/8A+vaT/wBBNWxVXV/+QJf/APXtJ/6CamXwsmXws5Kz/wCPKD/rmv8AKrIqvZf8eUH/AFzX+VWRRH4UEfhQ4VFcQLLGQRUwp2MiqKPMfGGgySxmW0cxXCZKkcBvY15jLdfupoL2MpcDg/LjJr6H1TT/ALRGcCvP9T8Kpc3GZLdXIPUivWwGPpUUo14cyTTTWkk1rv1Xl8zOcW9mVfh9YPeaEVlU7fMOzPcf/rzT/EnhD7QpVfkbOVYDOK7bw1pX2OFVCBVA4AGAK6C401Jxyormr42c8XLFU/dbd15FKPu8rOC8GaRewWqwXu1mjO1XU5DL2/HtXRa1oyyWhIXnFb9nYLb9BVueASxFSK5ak3Um5vdjSsfNeraXdaLrRu7aFniyWKquQPUH2rSj8OWGqwx3VvEyJINw8s4H5dBXq2oeGxJcbwver2m+HYIkx5Srk5OBjJ9a9OecYiUIcrcZxVuZNq66J97dGQqaOG8LeF7WwukljtFMoPEjjcw+men4V6iInNljvipbbS4YcEKK0BENmMV5tWtUrS56knJ927lpJbHg/jvQ4hcSajNbSuY8b2hbDBfX3xXb/DLVLHWNNZrYsJIGCSJJjcPQ8dj/AENb+t6Ss6t+7DBhggjIIql4T0Cy0RnFlZRQF+GZV+ZvqetdTxMJ4X2VW7lF+7rol1Vv8hWtK6O5QcVIKZH90VIK4Shwqrq//IEv/wDr2k/9BNWxVXV/+QJf/wDXtJ/6CamXwsmXws5Ky/48rf8A65r/ACqyK5mLWrmKJI1SIhFCjIPb8ak/t+6/55w/98n/ABrKNaNkZxqxsjpRThXM/wDCQ3f/ADzg/wC+T/jS/wDCRXf/ADzg/wC+T/jVe2iP20Tp9oYc1E1lGxyVFc9/wkl5/wA8oP8Avk/40v8Awkt5/wA8oP8Avk/40e2iHtonTxQrGOBU4Fcl/wAJPe/88rf/AL5b/Gl/4Si9/wCeVv8A98t/jR7aIe2ideBTwK47/hKr7/nlb/8AfLf40v8Awld9/wA8rb/vlv8AGj20Q9tE7Dy1bqKekYXoK43/AIS2/wD+eNt/3y3+NL/wl+of88bb/vlv/iqPbRD20TtgKeK4f/hMNQ/542v/AHy3/wAVS/8ACZaj/wA8bX/vlv8A4qj20Q9tE7Z4VkHIpIrZEOQK4v8A4TPUf+eNr/3w3/xVL/wmupf88LT/AL4b/wCKo9tEPbRO9UYp4rgP+E21L/nhaf8AfDf/ABVL/wAJxqf/ADwtP++G/wDiqPbRD20T0EVV1f8A5Aeof9e0n/oJriv+E51P/nhaf98N/wDFVHc+M9RurWa3eG1CSoyMVVsgEY4+aplWjZilVjZn/9k=" alt="Google Logo">

就可以展示了

 

 AjaxResult是一个封装的用于返回数据的对象 

如有需要,在下面

package com.hyh.ad.common.core.domain;



import cn.hutool.http.HttpStatus;
import com.hyh.ad.common.utils.StringUtils;

import java.util.HashMap;

/**
 * 操作消息提醒
 * 
 * @author pd
 */
public class AjaxResult extends HashMap<String, Object>
{
    private static final long serialVersionUID = 1L;

    /** 状态码 */
    public static final String CODE_TAG = "code";

    /** 返回内容 */
    public static final String MSG_TAG = "msg";

    /** 数据对象 */
    public static final String DATA_TAG = "data";

    /**
     * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
     */
    public AjaxResult()
    {
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     * 
     * @param code 状态码
     * @param msg 返回内容
     */
    public AjaxResult(int code, String msg)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
    }

    /**
     * 初始化一个新创建的 AjaxResult 对象
     * 
     * @param code 状态码
     * @param msg 返回内容
     * @param data 数据对象
     */
    public AjaxResult(int code, String msg, Object data)
    {
        super.put(CODE_TAG, code);
        super.put(MSG_TAG, msg);
        if (StringUtils.isNotNull(data))
        {
            super.put(DATA_TAG, data);
        }
    }

    /**
     * 返回成功消息
     * 
     * @return 成功消息
     */
    public static AjaxResult success()
    {
        return AjaxResult.success("操作成功");
    }

    /**
     * 返回成功数据
     * 
     * @return 成功消息
     */
    public static AjaxResult success(Object data)
    {
        return AjaxResult.success("操作成功", data);
    }

    /**
     * 返回成功消息
     * 
     * @param msg 返回内容
     * @return 成功消息
     */
    public static AjaxResult success(String msg)
    {
        return AjaxResult.success(msg, null);
    }

    /**
     * 返回成功消息
     * 
     * @param msg 返回内容
     * @param data 数据对象
     * @return 成功消息
     */
    public static AjaxResult success(String msg, Object data)
    {
        return new AjaxResult(HttpStatus.HTTP_OK, msg, data);
    }

    /**
     * 返回错误消息
     * 
     * @return
     */
    public static AjaxResult error()
    {
        return AjaxResult.error("操作失败");
    }

    /**
     * 返回错误消息
     * 
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult error(String msg)
    {
        return AjaxResult.error(msg, null);
    }

    /**
     * 返回错误消息
     * 
     * @param msg 返回内容
     * @param data 数据对象
     * @return 警告消息
     */
    public static AjaxResult error(String msg, Object data)
    {
        return new AjaxResult(HttpStatus.HTTP_INTERNAL_ERROR, msg, data);
    }

    /**
     * 返回错误消息
     * 
     * @param code 状态码
     * @param msg 返回内容
     * @return 警告消息
     */
    public static AjaxResult error(int code, String msg)
    {
        return new AjaxResult(code, msg, null);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/701575.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言 sizeof 和 strlen

目录 一、sizeof 和 strlen 的区别 a.sizeof b.strlen c.sizeof与strlen的区别 二、数组和指针笔试题解析(32位环境) a.一维数组( int a[ ] { 1 , 2 , 3 , 4 } ) b.字符数组 &#xff08;char arr[ ] {a , b , c , d , e , f }&#xff09; &#xff08; char arr[ …

Ubuntu系统调试分析工具

文章目录 一、火焰图一、下载 FlameGraph二、安装 iperf三、使用二、Lockdep1、内核开启 Lockdep 配置2、判断 Lockdep 开启是否成功一、火焰图 一、下载 FlameGraph git clone https://github.com/brendangregg/FlameGraph.gitFlameGraph 介绍:   基本思想是将程序的函数…

vue生成二维码中间自定义logo并截图分享

需求描述&#xff1a;在公众号中&#xff0c;生成二维码&#xff0c;并在二维码中央添加自定义logo&#xff0c;然后生成一张分享给好友的 二维码图片。 一、用到的依赖包 npm install --save html2canvas <script srchttps://cdn.staticfile.org/jquery/2.1.1/jquery.min…

nvm 安装说明

1、下线nvm地址 https://nvm.uihtm.com/2、安装步骤 2.1、双击解压后的exe 2.2、选择I accept…&#xff0c;然后点击next 2.3、选择nvm安装位置,选择好后点击next 2.4、选择nodejs的安装位置&#xff0c;点击next&#xff0c;记住你的nodejs路径&#xff01;甚至可以复制这…

[数据集][目标检测]叶子计数检测数据集VOC+YOLO格式240张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;240 标注数量(xml文件个数)&#xff1a;240 标注数量(txt文件个数)&#xff1a;240 标注类别…

C语言的数据结构:串、数组、广义表

一、串 1、串的定义 串是一个线性表&#xff0c;但其节点中的内容只能为字符&#xff0c;所以也称为字符串。 字符串中可以有多个字符&#xff0c;也可以没有字符。没有字符的叫作&#xff1a;空串。 空串&#xff1a;""。 有值的串&#xff1a;"1123"。 只…

Handler通信机制

目标&#xff1a; 1.Handler和Looper什么关系&#xff1f; 一个Looper对应一个MessageQueue&#xff0c;可以多个handler往MessageQueue发送消息。 2.一个线程有几个Handler&#xff1f; 3.Handler内存泄漏的原因&#xff1f; 4.使用Message时如何创建它&#xff1f; 5.子…

重生奇迹MU剑士介绍

剑士拥有过人的体力及华丽的剑术&#xff0c;加上属于近距离攻击型职业&#xff0c;就算没有其他角色的帮助也可自行锻炼。由于剑士是剑术的专家&#xff0c;所以无法学习魔法&#xff0c;但与其他角色组队冒险时&#xff0c;因优异的体力通常是担任先锋角色。剑士等级达到150级…

SSM 离散数学线上考试系统-计算机毕业设计源码83059

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;高校当然也不例外。离散数学线上考试系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;采…

VB.NET实现上位机自动识别可用串口

在实际应用中有时会牵扯到挑选可用串口&#xff0c;比如上位机和从站设备使用Modbus RTU协议进行通讯时需要选择COM串口&#xff0c;每次启动连接前都在设备管理器查看较为麻烦&#xff0c;可以设置一个串口自动识别功能&#xff0c;如果选择了错误的串口还可以提示串口选择错误…

借助Historian Connector + TDengine,打造工业创新底座

在工业自动化的领域中&#xff0c;数据的采集、存储和分析是实现高效决策和操作的基石。AVEVA Historian (原 Wonderware Historian) 作为领先的工业实时数据库&#xff0c;专注于收集和存储高保真度的历史工艺数据。与此同时&#xff0c;TDengine 作为一款专为时序数据打造的高…

排名前五的 Android 数据恢复软件

正在寻找数据恢复软件来从 Android 设备恢复数据&#xff1f;本指南将为您提供 5 款最佳 Android 数据恢复软件。浏览这些软件&#xff0c;然后选择您喜欢的一款来恢复 Android 数据。 ndroid 设备上的数据丢失可能是一种令人沮丧的经历&#xff0c;无论是由于意外删除、系统崩…

【Redis】Redis常见问题——缓存更新/内存淘汰机制/缓存一致性

目录 回顾数据库的问题如何提高 mysql 能承担的并发量&#xff1f;缓存解决方案应对的场景 缓存更新问题定期生成如何定期统计定期生成的优缺点 实时生成maxmemory 设置成多少合适呢&#xff1f;项目类型上来说 新的问题 内存淘汰策略Redis淘汰策略为什么redis要内存淘汰内存淘…

Echarts自定义地图显示区域,可以显示街道,小区,学校等区域

&#x1f680;&#x1f680;​​​​​​​&#x1f680;​​​​​​​目录 自定义地图 1. 选择边界生成器 2.导出JSON&#xff0c;在vue中使用&#xff1a; 3. vue中使用自定义地图 4.两个面、两条线&#xff0c;4个features&#xff0c;在每一个properties中添加name属…

英语四六级考试听力同频无线转发系统在上海电子信息职业技术学院的应用

英语四六级考试听力同频无线转发系统在上海电子信息职业技术学院的应用 由北京海特伟业科技有限公司任洪卓发布于2024年6月12日 一、 英语考试听力同频无线转发系统建设背景 英语听力考试作为评估大学生英语能力的重要一环&#xff0c;其顺利进行对于保障考试公平性和学生权益…

6月报名 | 海克斯康Actran风机类气动噪声分析培训

您好&#xff01;感谢您长期以来对优飞迪科技与海克斯康的关注与支持。我们诚邀您参加海克斯康Actran风机类气动噪声分析培训&#xff0c;特邀海克斯康原厂讲师将以实操为基础&#xff0c;结合真实案例&#xff0c;手把手帮您解锁噪声仿真关键技术。 活动主题&#xff1a; 海…

金石传拓非遗技艺端午专场活动之精彩瞬间

6月10日端午节下午&#xff0c;由致公党润州区基层委二支部举办的“凝心铸魂强根基&#xff0c;端午追远贺盛世”金石传拓体验活动在镇江万达广场隆重举行。近30名党员及其家属参加了本次活动&#xff0c;活动由润州区二支部主委吴娉主持。 端午节&#xff0c;又称端阳节&#…

视频转换器推荐哪个好?多款视频转换器任你选

#快要溢出来的分享欲# 在数字化时代&#xff0c;视频已成为我们生活中不可或缺的一部分。无论是观看电影、学习课程还是记录生活&#xff0c;视频都扮演着重要角色。 然而你也知道&#xff0c;现在的视频格式五花八门&#xff0c;想在不同的设备上播放&#xff0c;就得转换格…

加速下载2024IDM下载器让网速飞起来!

网速慢&#xff0c;文件大&#xff0c;下载难。 这或许是很多人的上网日常。 尤其是当下载进度达到99.8%时&#xff0c;突然提示你下载失败&#xff0c;需要重新来过…… IDM马丁版下载如下: https://wm.makeding.com/iclk/?zoneid34275 idm最新绿色版一键安装包链接&#…

潇洒郎: 腾讯DDNS域名解析, DNSPod API使用示例—实时更新本地IPV6地址到DNS解析

1、新人一元购买一个域名 (到期后换身份,对于小白来说,玩玩域名而已,家人的身份就足够用几年了) 2、域名操作 查看我的域名信息 点击管理DNS解析 点击解析 如果之前有解析记录,则可导出 下载解压 查看一下