SpringBoot中使用kaptcha生成验证码

news2025/3/16 11:58:19

简介

kaptcha是谷歌开源的简单实用的验证码生成工具。通过设置参数,可以自定义验证码大小、颜色、显示的字符等等。

Maven引入依赖

	<!-- https://mvnrepository.com/artifact/pro.fessional/kaptcha -->
    <dependency>
         <groupId>pro.fessional</groupId>
         <artifactId>kaptcha</artifactId>
         <version>2.3.3</version>
     </dependency>

新增配置类

  • CaptchaConfig.java
package com.example.learn.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.*;

@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.example.learn.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;
    }
}

  • KaptchaTextCreator
package com.example.learn.config;

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

import java.util.Random;

/**
 * 验证码文本生成器
 *
 * @author ruoyi
 */
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 = random.nextInt(3);
        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 (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]);
            }
        }
        suChinese.append("=?@" + result);
        return suChinese.toString();
    }
}

简单使用

后端控制器

  • CaptchaController
package com.example.learn.controller;


import cn.hutool.core.util.IdUtil;
import com.example.learn.common.returns.CommonResult;
import com.google.code.kaptcha.Producer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

/**
 *  验证码操作处理
 */

@RestController
public class CaptchaController {

    @Resource(name = "captchaProducer")
    private Producer captchaProducer;
    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;
    
/*    @Autowired
    private StringRedisTemplate redisTemplate;*/

    // 验证码类型可以是char/math
    public static String CAPTCHA_TYPE = "char";
    
    public static String CAPTCHA_KEY_PREFIX = "captcha:";

    @GetMapping(value = "/captchaImage")
    public CommonResult captchaImage() {
        String capStr = null;
        String code = null;
        BufferedImage image = null;
        if ("math".equals(CAPTCHA_TYPE)) {
            // 1+2=?@3
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        } else if ("char".equals(CAPTCHA_TYPE)) {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }
        // 转换流信息写出
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image,"jpg",os);
        } catch (IOException e) {
            return CommonResult.error(e.getMessage());
        }
        // 若用到了redis,放开下面注释代码,并且联调时前端需要把返回的uuid传回来
        String uuid = IdUtil.simpleUUID();
        /*String captchaKey = CAPTCHA_KEY_PREFIX + uuid;
        // 将code到redis中
        redisTemplate.opsForValue().set(captchaKey,code,2, TimeUnit.MINUTES);*/
        
        CommonResult commonResult = CommonResult.success();
        commonResult.put("uuid",uuid);
        commonResult.put("img", Base64.getEncoder().encodeToString(os.toByteArray()));
        return commonResult;
    }
}


前端页面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>显示 Base64 图片</title>
    <style>
        .container {
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
        }
        .image-container {
            margin-top: 20px;
            text-align: center;
        }
        img {
            max-width: 100%;
            height: auto;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>显示 Base64 图片</h1>
        <div class="image-container">
            <img id="base64Image" src="" alt="Base64 图片">
        </div>
        <button onclick="loadImage()">加载图片</button>
    </div>

    <script>
        // 模拟从后端获取的 Base64 数据
        function getBase64ImageData() {
            // 这里是一个示例的 Base64 图片数据(一个简单的 PNG 图片)
            return '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';
        }

        // 加载图片
        function loadImage() {
            const base64Data = getBase64ImageData();
            const img = document.getElementById('base64Image');
            img.src = 'data:image/jpg;base64,' + base64Data;
        }

        // 页面加载时直接显示图片
        window.onload = function() {
            loadImage();
        };
    </script>
</body>
</html>

说明: 将后端接口返回的img的值复制到前端页面的 function getBase64ImageData()中

效果:

  • 验证码类型:math
    在这里插入图片描述
  • 验证码类型:char
    在这里插入图片描述

其他相关代码

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>learn</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>learn</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.5.15</spring-boot.version>
        <spring-framework.version>5.3.39</spring-framework.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- redis 缓存操作 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/pro.fessional/kaptcha -->
        <dependency>
            <groupId>pro.fessional</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.36</version>
        </dependency>


    </dependencies>
    <dependencyManagement>
        <dependencies>
            <!-- 覆盖SpringFramework的依赖配置-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>${spring-framework.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.example.learn.LearnApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>


</project>
  • CommonResult.java
package com.example.learn.common.returns;

import java.util.HashMap;
import java.util.Objects;

public class CommonResult extends HashMap<String, Object> {


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * 是否为成功消息
     *
     * @return 结果
     */
    public boolean isSuccess()
    {
        return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
    }

    /**
     * 是否为警告消息
     *
     * @return 结果
     */
    public boolean isWarn()
    {
        return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
    }

    /**
     * 是否为错误消息
     *
     * @return 结果
     */
    public boolean isError()
    {
        return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
    }

    /**
     * 方便链式调用
     *
     * @param key 键
     * @param value 值
     * @return 数据对象
     */
    @Override
    public CommonResult put(String key, Object value)
    {
        super.put(key, value);
        return this;
    }
}

  • HttpStatus.java
package com.example.learn.common.returns;

/**
 * 返回状态码
 * 
 * @author ruoyi
 */
public class HttpStatus
{
    /**
     * 操作成功
     */
    public static final int SUCCESS = 200;

    /**
     * 对象创建成功
     */
    public static final int CREATED = 201;

    /**
     * 请求已经被接受
     */
    public static final int ACCEPTED = 202;

    /**
     * 操作已经执行成功,但是没有返回数据
     */
    public static final int NO_CONTENT = 204;

    /**
     * 资源已被移除
     */
    public static final int MOVED_PERM = 301;

    /**
     * 重定向
     */
    public static final int SEE_OTHER = 303;

    /**
     * 资源没有被修改
     */
    public static final int NOT_MODIFIED = 304;

    /**
     * 参数列表错误(缺少,格式不匹配)
     */
    public static final int BAD_REQUEST = 400;

    /**
     * 未授权
     */
    public static final int UNAUTHORIZED = 401;

    /**
     * 访问受限,授权过期
     */
    public static final int FORBIDDEN = 403;

    /**
     * 资源,服务未找到
     */
    public static final int NOT_FOUND = 404;

    /**
     * 不允许的http方法
     */
    public static final int BAD_METHOD = 405;

    /**
     * 资源冲突,或者资源被锁
     */
    public static final int CONFLICT = 409;

    /**
     * 不支持的数据,媒体类型
     */
    public static final int UNSUPPORTED_TYPE = 415;

    /**
     * 系统内部错误
     */
    public static final int ERROR = 500;

    /**
     * 接口未实现
     */
    public static final int NOT_IMPLEMENTED = 501;

    /**
     * 系统警告消息
     */
    public static final int WARN = 601;
}

参考

  • kaptcha验证码组件
  • RuoYi-Vue-v3.8.9

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

蓝桥杯嵌入式赛道复习笔记1(led点亮)

前言 基础的文件创建&#xff0c;参赛资源代码的导入&#xff0c;我就不说了&#xff0c;直接说CubeMX的配置以及代码逻辑思路的书写&#xff0c;在此我也预祝大家人人拿国奖 理论讲解 原理图简介 1.由于存在PC8引脚到PC15引脚存在冲突&#xff0c;那么官方硬件给的解决方案…

六十天前端强化训练之第十七天React Hooks 入门:useState 深度解析

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、知识讲解 1. Hooks 是什么&#xff1f; 2. useState 的作用 3. 基本语法解析 4. 工作原理 5. 参数详解 a) 初始值设置方式 b) 更新函数特性 6. 注意事项 7. 类组…

芯科科技推出的BG29超小型低功耗蓝牙®无线SoC,是蓝牙应用的理想之选

具有扩大的内存和超低功耗特性的超小型BG29是互联健康设备的理想之选 低功耗无线领域内的领导性创新厂商Silicon Labs&#xff08;亦称“芯科科技”&#xff0c;NASDAQ&#xff1a;SLAB&#xff09;今日宣布&#xff1a;推出全新的第二代无线开发平台产品BG29系列无线片上系统…

export、export default 和 module.exports 深度解析

文章目录 1. 模块系统概述1.1 模块系统对比1.2 模块加载流程 2. ES Modules2.1 export 使用2.2 export default 使用2.3 混合使用 3. CommonJS3.1 module.exports 使用3.2 exports 使用 4. 对比分析4.1 语法对比4.2 使用场景 5. 互操作性5.1 ES Modules 中使用 CommonJS5.2 Com…

qwen2.5-vl多机多卡分布式部署

记录一下工作中进行多机多卡部署qwen2.5-vl多模态大模型踩过的坑 第一个天坑就是官方提供的镜像qwenllm/qwenvl:2.5-cu121有问题&#xff0c;在titan显卡会抛出cuda error:no kernel image is availabe for execution on the device. 这是cuda内核与GPU不兼容的问题&#xff0c…

【红黑树】—— 我与C++的不解之缘(二十五)

前言 学习了avl树&#xff0c;现在来学习红黑树。 一、什么是红黑树 红黑树是一颗平衡二叉搜索树&#xff0c;它每一个节点增加了一个存储位表示节点的颜色&#xff0c;可以是红色或者黑色。 相比较于AVL树&#xff0c;红黑树也是一个自平衡二叉搜索树&#xff0c;但是它与AVL树…

驾驭 DeepSeek 科技之翼,翱翔现代学习新天际

在当今这个信息爆炸的时代&#xff0c;学习的方式和途径正在经历着前所未有的变革。人工智能技术的飞速发展&#xff0c;为我们的学习带来了全新的机遇和挑战。DeepSeek 作为一款强大的大语言模型&#xff0c;凭借其卓越的性能和丰富的功能&#xff0c;为现代学习注入了新的活力…

DeepSeek本地部署 (Windows+Ollama+Docker Desktop+ RAGFlow)

适用场景&#xff1a; 1、商城的小机器人自动根据实际情况回复 2、需要7*24小时运行在线回复&#xff0c;如&#xff1a;在线购物、在线咨询、在线招生等 3、无人值守环境 2025年1月&#xff0c;DeepSeek 正式发布 DeepSeek-R1 推理大模型&#xff0c;DeepSeek-R1 成本价格低…

SPI驱动(八) -- SPI_DAC设备驱动程序

文章目录 参考资料&#xff1a;一、编写设备树二、 编写驱动程序三、编写测试APP四、Makefile五、上机实验 参考资料&#xff1a; 参考资料&#xff1a; 内核头文件&#xff1a;include\linux\spi\spi.h内核文档&#xff1a;Documentation\spi\spidevDAC芯片手册&#xff1a;…

MySQL 衍生表(Derived Tables)

在SQL的查询语句select …. from …中&#xff0c;跟在from子句后面的通常是一张拥有定义的实体表&#xff0c;而有的时候我们会用子查询来扮演实体表的角色&#xff0c;这个在from子句中的子查询会返回一个结果集&#xff0c;这个结果集可以像普通的实体表一样查询、连接&…

HarmonyOS NEXT开发进阶(十二):build-profile.json5 文件解析

文章目录 一、前言二、Hvigor脚本文件三、任务与任务依赖图四、多模块管理4.1 静态配置模块 五、分模块编译六、配置多目标产物七、配置APP多目标构建产物八、定义 product 中包含的 target九、拓展阅读 一、前言 编译构建工具DevEco Hvigor&#xff08;以下简称Hvigor&#x…

深度学习笔记(37周)

目录 摘要 Abstracts 1. 介绍 2. 相关工作 3. 模型 3.1 时序段网络TSN 3.2 学习时序段网络 4. 训练结果 5. 结论 摘要 本周阅读的论文是《Temporal Segment Networks: Towards Good Practices for Deep Action Recognition》。作者主要想通过较少的训练样本&#xff…

ELK+Filebeat+Kafka+Zookeeper安装部署

1.安装zookeeper zookpeer下载地址:apache-zookeeper-3.7.1-bin.tar.gzhttps://link.csdn.net/?targethttps%3A%2F%2Fwww.apache.org%2Fdyn%2Fcloser.lua%2Fzookeeper%2Fzookeeper-3.7.1%2Fapache-zookeeper-3.7.1-bin.tar.gz%3Flogin%3Dfrom_csdn 1.1解压安装zookeeper软件…

【软考-架构】3.3、模式分解-事务并发-封锁协议

✨资料&文章更新✨ GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目录 模式分解&#xff08;难点&#xff09;无损分解&#x1f4af;考试真题并发控制封锁协议&#x1f4af;考试真题第一题第二题 模式分解&#xff08;难点&#xff09; 保持函…

审批工作流系统xFlow

WorkFlow-审批流程系统 该项目为完全开源免费项目 可用于学习或搭建初始化审批流程系统 希望有用的小伙伴记得点个免费的star gitee仓库地址 仿钉钉飞书工作审批流系统 介绍 前端技术栈: vue3 ts vite arcodesign eslint 后端技术栈:springbootspring mvc mybatis mavenmysq…

【数据结构初阶第十九节】八大排序系列(下篇)—[详细动态图解+代码解析]

hello&#xff0c;好久不见&#xff01; 云边有个稻草人-CSDN博客 上篇内容&#xff0c;回顾一下吧【数据结构初阶第十八节】八大排序系列(上篇)—[详细动态图解代码解析]-CSDN博客 今天我们来学习下篇 目录 &#xff08;2&#xff09;快速排序 【挖坑法】 —思路 —思路…

定制开发开源 AI 智能名片 S2B2C 商城小程序源码在小程序直播营销中的应用与价值

摘要&#xff1a; 本文主要探讨了定制开发开源 AI 智能名片 S2B2C 商城小程序源码在小程序直播营销中的应用与价值。首先详细阐述了小程序直播的基本概念、特点、发展历程及营销意义&#xff0c;包括其便捷性、广泛的受众连接能力以及对企业推广的重要作用。接着深入剖析了定制…

蓝桥杯Python赛道备赛——Day3:排序算法(二)(归并排序、堆排序、桶排序)

本博客是蓝桥杯备赛系列中排序算法的第二期&#xff0c;包括&#xff1a;归并排序、堆排序和桶排序。每一个算法都在给出概念解释的同时&#xff0c;给出了示例代码&#xff0c;以供低年级师弟师妹们学习和练习。 由于本期的三个算法的复杂度相对来说要高于上一期的三个算法&am…

Type-C:智能家居的电力革命与空间美学重构

在万物互联的时代浪潮中&#xff0c;家居空间正经历着从功能容器到智慧终端的蜕变。当意大利设计师安东尼奥奇特里奥提出"消失的设计"理念二十年后&#xff0c;Type-C充电技术正以润物无声的方式重塑着现代家居的形态与内核&#xff0c;开启了一场静默的居住革命。 【…

第十五届蓝桥杯C/C++组:宝石组合题目(从小学奥数到编程题详解)

这道题目真的一看就不好做&#xff0c;如果直接暴力去做百分之90必挂掉&#xff0c;那么这道题目到底应该怎么去做呢&#xff1f;这我们就得从小学奥数开始聊了。&#xff08;闲话&#xff1a;自从开始蓝桥杯备赛后&#xff0c;每天都在被小学奥数震惊&#xff0c;为什么我小的…