springboot基础及上传组件封装

news2024/10/6 14:36:27

简介

本文主要以文件上传为demo,介绍了一些 springboot web 开发的入门的技术栈。

对应刚接触 springboot 的可以参考下。

主要包括文件md5比对、生成图片缩略图、数据库迁移、文件记录持久化、请求全局异常处理等功能。

准备工作

  • idea 中创建项目,java8 , springboot 2

  • maven 所需依赖
<?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.bimcc</groupId>
    <artifactId>iot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>iot</name>
    <description>iot</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.6.13</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--数据库迁移 -->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
            <version>5.2.4</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--请求验证-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.7.8</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>20.0</version>
        </dependency>

        <!--工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.4.0</version>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <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.bimcc.iot.IotApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

  • 创建项目目录

在这里插入图片描述

目录意义如下:

请添加图片描述

  • 修改 application.yml 配置:

---
# 开发环境的配置
server:
  port: 9090
spring:
  controller:
    api-prefix: /api
  flyway:
    enabled: true #开启数据迁移
    table: flyway_schema_history #用于存储迁移历史记录的表名,默认为flyway_schema_history
    baseline-on-migrate: true #当迁移数据库存在但没有元数据的表时,自动执行基准迁移,新建flyway_schema_history表
    locations: classpath:db/migration #数据库迁移脚本的位置,默认为classpath:db/migration,classpath 羡慕resources目录
    clean-disabled: true #用于控制是否禁用 Flyway 的 clean 操作。
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/java_iot?serverTimezone=GMT%2b8
  config:
    activate:
      on-profile: dev #开发环境
  servlet:
    multipart:
      enabled: true # 允许文件上传
      max-file-size: 20971520 # 单文件最大限制 20M
      max-request-size: 52428800 # 单次请求最大限制 50M
file:
  upload:
    path: E:\project-java\java-upload  # 文件上传保存服务器绝对路径
    suffix: jpg,jpeg,png,bmp,xls,xlsx,pdf  # 文件上传保存路径
    is-thumb: true  # 是否开启缩略图 true false
    proportion: 5  # 缩略图缩放比例
    path-pattern: uploads  # 访问虚拟目录
log:
  level: INFO # INFO DEBUG ERROR
---

# 当前启用的配置
spring:
  application:
    name: iot # 应用平台
  profiles:
    active: dev   # 当前环境
  • 创建数据表迁移文件

在这里插入图片描述

写入以下内容:

CREATE TABLE sys_file
(
    id         INT AUTO_INCREMENT COMMENT 'id',
    file_name  VARCHAR(255) NOT NULL COMMENT '文件名称',
    ip         VARCHAR(255) COMMENT '上传ip',
    file_path  VARCHAR(255) NOT NULL COMMENT '文件路径',
    thumb_path  VARCHAR(255) COMMENT '缩略图文件路径',
    file_size  INT COMMENT '字节大小',
    file_type  VARCHAR(255) COMMENT '文件类型',
    file_ext   CHAR(36) COMMENT '文件后缀',
    file_md5   VARCHAR(255) COMMENT '文件md5',
    created_at DATETIME COMMENT '创建时间',
    updated_at DATETIME COMMENT '修改时间',
    deleted_at DATETIME COMMENT '删除时间',
    PRIMARY KEY (id)
) ENGINE = InnoDB DEFAULT CHARSET = UTF8MB4;

创建上传实体类

  • dto目录 创建 BaseEntity FileEntity 实体类

BaseEntity 写入以下内容:


// 省略 package import 

@Data
public class BaseEntity implements Serializable {

    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;


    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") //格式化时间,空值不会格式化
    @TableField(value = "created_at",fill = FieldFill.INSERT)
    @JsonProperty("created_at") //json格式化显示字段
    private Date createdAt;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField(value = "updated_at",fill = FieldFill.INSERT_UPDATE)
    @JsonProperty("updated_at")
    private Date updatedAt;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @JsonProperty("deleted_at")
    @TableField(value = "deleted_at")
    @TableLogic(value = "null",delval = "now()")
    private Date deletedAt;

}

FileEntity 写入以下内容:

// 省略 package import 
@Data
@TableName("sys_file")
public class FileEntity extends BaseEntity {
    @TableField(value = "file_name")
    private String fileName;
    @TableField(value = "ip")
    private String ip;
    @TableField(value = "file_path")
    private String filePath;
    @TableField(value = "thumb_path")
    private String thumbPath;
    @TableField(value = "file_size")
    private Long fileSize;
    @TableField(value = "file_type")
    private String fileType;
    @TableField(value = "file_ext")
    private String fileExt;
    @TableField(value = "file_md5")
    private String fileMd5;
}


  • 创建 mapper , 在 mapper 目录创建 FileMapper 接口类
// 省略 package import 

@Mapper
public interface FileMapper extends BaseMapper<FileEntity> {

    FileEntity queryByMd5(String md5);
}

  • 创建 mapper xml 文件。在 resources 目录下面创建 mapper 目录,然后再创建 FileMapper.xml。并写入以下内容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bimcc.iot.mapper.FileMapper">

    <!-- 询的结果集字段和实体类的user属性名不一致,自定义查询结果集的映射规则   -->
    <resultMap id="queryFile" type="com.bimcc.iot.dto.FileEntity">
        <id property="id" column="id"/>
        <result property="fileName" column="file_name"/>
        <result property="ip" column="ip"/>
        <result property="filePath" column="file_path"/>
        <result property="fileSize" column="file_size"/>
        <result property="fileType" column="file_type"/>
        <result property="fileExt" column="file_ext"/>
        <result property="fileMd5" column="file_md5"/>
        <result property="createdAt" column="created_at"/>
        <result property="updatedAt" column="updated_at"/>
        <result property="deletedAt" column="deleted_at"/>
    </resultMap>

    <select id="queryByMd5" resultMap="queryFile">
        select * from sys_file where file_md5 = #{md5} and deleted_at is null
    </select>


</mapper>

全局异常处理

  • exceptin 目录里面创建 ServiceException 类,编写如下代码:
// 省略 package import 

//专用于处理业务层的异常基类
public class ServiceException extends RuntimeException{
    public ServiceException() {
        super();
    }

    public ServiceException(String message) {
        super(message);
    }

    public ServiceException(String message, Throwable cause) {
        super(message, cause);
    }

    public ServiceException(Throwable cause) {
        super(cause);
    }

    protected ServiceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

  • controller 目录里面创建 BaseController 基类,后续 controller 继承他
// 省略 package import 

@ControllerAdvice
public class BaseController {
    public static final int OK = 200;

    /**
     * 全局手动抛出异常处理
     * 1.当出现了value内的异常之一,就会将下方的方法作为新的控制器方法进行执行
     *   因此该方法的返回值也同时是返回给前端的页面
     * 2.此外还自动将异常对象传递到此方法的参数列表中,这里使用Throwable e来接收
     **/
    @ExceptionHandler(ServiceException.class) //统一处理抛出的异常
    public ResJson<Void> handleException(Throwable e){
        ResJson<Void> result = new ResJson<>(e);
        result.setCode(5000); //数据库或服务器有问题
        return result;
    }


}

注册配置

config 目录创建 GlobalControllerPathPrefixConfig 类,写入以下内容:

// 省略 package import 

//群集统一配置接口前缀
@Configuration
public class GlobalControllerPathPrefixConfig implements WebMvcConfigurer {


    @Value("${spring.controller.api-prefix}")
    private String pathPrefix;

    @Value("${file.upload.path-pattern}")
    private String pathPattern;

    @Value("${file.upload.path}")
    private String fileUploadPath;

    //全局接口注册 api前缀
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.addPathPrefix(pathPrefix, c -> c.isAnnotationPresent(RestController.class));
    }

    //静态资源图片上传,虚拟路径返回
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //将匹配上/files/**虚拟路径的url映射到文件上传到服务器的目录,获取静态资源
        registry.addResourceHandler("/" +pathPattern + "/**").addResourceLocations("file:" + fileUploadPath+File.separator);
        WebMvcConfigurer.super.addResourceHandlers(registry);
    }


}

创建工具类

  • 创建一个全局返回类。在 utils 里面创建一个 ResJson 类型
// 省略 import

@Data
public class ResJson<E> implements Serializable {
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 提示信息
     */
    private String message;
    /**
     * 返回数据
     */
    private E data;

    public ResJson(Integer code) {
        this.code = code;
    }
    public ResJson(Integer code,String message) {
        this.code = code;
        this.message = message;
    }

    public ResJson(Throwable e) {
        this.message = e.getMessage();
    }

    public ResJson(Integer code,String message,E data) {
        this.code = code;
        this.data = data;
        this.message = message;
    }

}

  • 创建一个 md5 加密类。在 utils 里面创建一个 PasswordEncryptedUtils 类型
// 省略 package import 
public class PasswordEncryptedUtils {

    public static String getPasswordByMD5(String pwd,String salt){
        for (int i = 0; i < 3 ; i++) {
            //md5加密算法的调用
            pwd =  DigestUtils.md5DigestAsHex((salt + pwd + salt).getBytes()).toUpperCase();
        }
        //返回经过加密的结果
        return pwd;
    }
}

创建上传服务

  • server目录里面创建FileServer 接口类
// 省略 package import 

public interface FileServer {

    FileEntity upload(MultipartFile file);

    String createThumb(String fileDir,String filePath,String fileName,String suffix);

}

  • server目录里面创建impl目录并在里面创建FileServerImpl类实现上面的接口功能

// 省略 package import 

@Service
public class FileServerImpl implements FileServer {

    public static final int maxWidth = 100;

    //拦截的url,虚拟路径
    public String pathPattern = "uploads";

    //文件磁盘路径
    @Value("${file.upload.path}")
    private String fileUploadPath;

    @Value(value = "${file.upload.suffix:jpg,jpeg,png,bmp,xls,xlsx,pdf}")
    private String fileUploadSuffix;

    @Value(value = "${file.upload.is-thumb}")
    private Boolean isThumb;

    @Value(value = "${file.upload.proportion}")
    private Integer proportion;

    @Autowired
    HttpServletRequest request;

    @Autowired
    FileMapper fileMapper;

    //文件上传
    @Override
    public FileEntity upload(MultipartFile file) {
        FileEntity fileRes = new FileEntity();

        if (file.isEmpty()) {
            // log.error("the file to be uploaded is empty");
            return fileRes;
        }
        List<String> suffixList = Lists.newArrayList(fileUploadSuffix.split(","));

        try {
            //校验文件后缀
            String originalFilename = file.getOriginalFilename();
            //获取文件类型
            String type = FileUtil.extName(originalFilename);
            //文件后缀
            String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            if (!suffixList.contains(suffix)) {
                //log.error("unsupported file format");
                return fileRes;
            }

            //获取文件md5
            String md5 = SecureUtil.md5(file.getInputStream());

            // 从数据库查询是否存在相同的记录
            FileEntity dbFiles = fileMapper.queryByMd5(md5);
            if (dbFiles != null) { // 文件已存在
                return dbFiles;
            }


            String year = new SimpleDateFormat("yyyy").format(new Date());
            String month = new SimpleDateFormat("MM").format(new Date());
            String day = new SimpleDateFormat("dd").format(new Date());

            String fileDir = fileUploadPath;
            String filePath = File.separator + year + File.separator + month + File.separator + day + File.separator;

            //首次需生成目录
            File folder = new File(fileDir + filePath);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            AtomicInteger counter = new AtomicInteger(0);
            String uniqueString = String.valueOf(Instant.now().toEpochMilli());

            String fileName = uniqueString + "." + suffix;
            String absolutePath = fileDir + filePath + fileName;
            file.transferTo(new File(absolutePath));
            //网页路径
            String dataFilePath = pathPattern + "/" + year + "/" + "/" + month + "/" + day + "/" + fileName;

            fileRes.setFilePath(dataFilePath);
            fileRes.setFileName(fileName);
            fileRes.setIp(request.getRemoteAddr());
            fileRes.setFileSize(file.getSize() / 1024);
            fileRes.setFileType(type);
            fileRes.setFileExt(suffix);
            fileRes.setFileMd5(md5);

            //判断是否生成缩率图
            if (isThumb) {
                createThumb(fileDir, filePath, uniqueString, suffix);
                String dataFileThumbPath = pathPattern + "/" + year + "/" + "/" + month + "/" + day + "/" + uniqueString + "_thumb." + suffix;
                fileRes.setThumbPath(dataFileThumbPath);
            }
            fileMapper.insert(fileRes);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        return fileRes;
    }

    //生成缩率图
    @Override
    public String createThumb(String fileDir, String filePath, String fileName, String suffix) {
        String localPath = fileDir + filePath + fileName + "." + suffix;
        String thumbPath = fileDir + filePath + fileName + "_thumb." + suffix;

        //判断缩略图是否存在
        Path path = Paths.get(thumbPath);
        if (Files.exists(path)) {
            return filePath + fileName + "_thumb." + suffix;
        }

        File originalFile = new File(localPath);
        try {
            BufferedImage originalImage = ImageIO.read(originalFile);
            int imageWidth = originalImage.getWidth();
            int imageHeight = originalImage.getHeight();

            double thumbWidth = 0;
            double thumbHeight = 0;
            if (imageWidth > maxWidth || imageHeight > maxWidth) {
                thumbWidth = (double) imageWidth / (double) proportion;
                thumbHeight = (double) imageHeight / (double) proportion;
            }
            if (thumbHeight > 0) {
                // 创建缩略图
                BufferedImage thumbnail = new BufferedImage((int) thumbWidth, (int) thumbHeight, BufferedImage.TYPE_INT_RGB);
                Graphics graphics = thumbnail.createGraphics();
                graphics.drawImage(originalImage.getScaledInstance((int) thumbWidth, (int) thumbHeight, Image.SCALE_SMOOTH), 0, 0, null);
                graphics.dispose();

                // 输出到文件
                ImageIO.write(thumbnail, suffix, new File(thumbPath));
                return filePath + fileName + "_thumb." + suffix;
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        return "";
    }


}

上传

  • 创建一个上传控制器UploadController,写入以下内容:
// 省略 package import 

@RestController
public class UploadController extends BaseController {

    @Autowired
    FileServer fileServer;


    @PostMapping("/upload")
    public ResJson<FileEntity> upload(@RequestParam MultipartFile file){
       FileEntity fileRes= fileServer.upload(file);
       return new ResJson<>(OK,"上传成功!",fileRes);
    }

}

  • 测试

通过 postman 接口测试,调用上面的上传接口

查看application.yml里面配置的上传目录,是否有文件

通过网络路径访问图片

总结

本文适合 springboot 入门的初学者。

以文件上传为demo,衍生出了一些常用功能,包含:文件上传,入库,请求。异常处理,api前缀,数据迁移,生成缩略图,等功能。

希望能对初学者有一个参考的作用。

– 欢迎点赞、关注、转发、收藏【我码玄黄】,gonghao同名

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

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

相关文章

PPP认证两种:PAP和CHAP,两次握手和三次握手

CHAP&#xff08;Challenge-Handshake Authentication Protocol&#xff0c;质询握手认证协议&#xff09;的设计理念是增强网络认证过程的安全性。在CHAP的三次握手过程中&#xff0c;不直接传送用户的明文密码&#xff0c;以此来提高安全性&#xff0c;具体步骤如下&#xff…

社交媒体数据恢复:QQ空间

本教程将指导您如何恢复QQ空间中的说说、日志和照片等内容。请注意&#xff0c;本教程不涉及推荐任何数据恢复软件。 一、恢复QQ空间说说 登录您的QQ账号&#xff0c;并进入QQ空间。点击“日志”选项&#xff0c;进入空间日志页面。在空间日志页面&#xff0c;您会看到一个“…

MyBatis源码分析--02:SqlSession建立过程

我们再来看看MyBatis使用流程&#xff1a; InputStream inputStream Resources.getResourceAsStream("myBatis_config.xml"); SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream); SqlSession session sqlSessionFactory.op…

【Rust日报】关于在其它语言中(特别是新语言中)能否直接调用Rust现有生态的研究...

关于在其它语言中&#xff08;特别是新语言中&#xff09;能否直接调用Rust现有生态的研究 直接调用&#xff0c;也就是不用写FFI绑定库。这篇文章讨论了其中的一些目前的困难&#xff0c;可以操作的一些方法。 本篇是第一篇&#xff1a;https://verdagon.dev/blog/exploring-s…

数学建模 —— 插值与拟合(1)

一、matlab画图 1.1 plot&#xff08;二维图形&#xff09; plot(x) —— 缺省自变量绘图格式 plot(x,y) —— 基本格式&#xff0c;以y(x)的函数关系作出直角坐标图&#xff0c;如果y为nm的矩阵&#xff0c;则以x为自变量&#xff0c;作出m条曲线 plot(x1,y1,x2,y2,…,xn,…

Lesson6--排序(初级数据结构完结篇)

【本节目标】 1. 排序的概念及其运用 2. 常见排序算法的实现 3. 排序算法复杂度及稳定性分析 1.排序的概念及其运用 1.1排序的概念 排序 &#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来…

GPT LoRA 大模型微调,生成猫耳娘

往期热门专栏回顾 专栏描述Java项目实战介绍Java组件安装、使用&#xff1b;手写框架等Aws服务器实战Aws Linux服务器上操作nginx、git、JDK、VueJava微服务实战Java 微服务实战&#xff0c;Spring Cloud Netflix套件、Spring Cloud Alibaba套件、Seata、gateway、shadingjdbc…

MACOS安装 vue 抱错解决方法npm ERR! code EACCESnpm ERR! syscall mkdirnpm ERR!

问题 在使用脚手架 vue-cli 创建 vue 工程的时候存在权限不足的情况下&#xff0c;报错&#xff1b; npm error code EACCES npm error syscall open npm error path /Users/ npm ERR! code EACCESnpm ERR! syscall mkdirnpm ERR! 解决方案&#xff1a; sudo npm cache cl…

什么是最好的手机数据恢复软件?6 款手机数据恢复软件 [2024 年更新]

什么是最好的手机数据恢复软件&#xff1f;在这篇文章中&#xff0c;您将了解 6 款最好的免费手机数据恢复软件&#xff0c;并学习如何恢复数据的完整指南。 最好的手机数据恢复软件是什么&#xff1f; 手机数据恢复软件是恢复智能手机中丢失或删除的文件、消息、照片和其他宝…

反射获取成员变量

目录 利用反射获取成员变量 ​编辑 代码实现 获取class对象 获取成员变量 获取单个成员变量 获取成员变量的名字 获取权限修饰符 获取成员变量的数据类型 获取成员变量记录的值 修改对象里面记录的值 利用反射获取成员变量 代码实现 Student类&#xff1a; 获取clas…

【 0 基础 Docker 极速入门】镜像、容器、常用命令总结

Docker Images&#xff08;镜像&#xff09;生命周期 Docker 是一个用于创建、部署和运行应用容器的平台。为了更好地理解 Docker 的生命周期&#xff0c;以下是相关概念的介绍&#xff0c;并说明它们如何相互关联&#xff1a; Docker&#xff1a; Docker 是一个开源平台&#…

生成ssh密钥,使用ssh连接linux系统

这里写目录标题 ssh密钥大概介绍1、密钥在哪里生成&#xff08;客户端/服务器&#xff09;&#xff1f;2、密钥生成是什么样子的&#xff1f; ssh &#xff08;生成密钥、密钥传输、配置连接、连接服务&#xff09;过程1、生成密钥提示一&#xff1a;输入保存密钥的文件&#x…

Nginx实战:nginx支持带下划线的header

nginx对header 的名字字符做了限制&#xff0c;默认 underscores_in_headers 为off&#xff0c;表示如果header name中包含下划线&#xff0c;则忽略掉&#xff0c;后端服务就获取不到该请求头。 为了支持header带下划线的参数&#xff0c;可以在http内或者server内设置如下参数…

ip地址告诉别人安全吗?ip地址告诉别人会有什么风险

IP地址告诉别人安全吗&#xff1f;在数字化时代&#xff0c;IP地址作为网络连接的关键标识符&#xff0c;承载着重要的安全意义。然而&#xff0c;很多人可能并不清楚&#xff0c;轻易地将自己的IP地址告诉他人可能带来一系列安全风险。那么&#xff0c;IP地址告诉别人会有什么…

7-11 验证宏(verify)---PTA实验C++

一、题目描述 无需惊慌&#xff0c;C缔造者Bjarne Stroustrup这句话说的CPP是C PreProcessor&#xff0c;即“C代码预处理器”。CPP根据#include #define #if #pragma等指令对文件进行处理。这种处理发生在编译之前&#xff0c;所以CPP叫“预处理器”。CPP完全是文本层面的处理…

少样本学习与零样本学习:理解与应用

少样本学习与零样本学习&#xff1a;理解与应用 在现代机器学习领域中&#xff0c;少样本学习&#xff08;Few-Shot Learning&#xff09;和零样本学习&#xff08;Zero-Shot Learning&#xff09;正变得越来越重要。这些技术能够在数据稀缺的情况下有效地进行学习和推理&…

禁止Windows Defender任务计划程序

开始键->搜索“任务计划程序”->“任务计划程序库”->“Microsoft”->"Windows"->"Windows Defender"->右边四项

Prometheus + Grafana + Alertmanager 系统监控

PrometheusGrafana 系统监控 1. 简介1.1 Prometheus 普罗 米修斯1.2 Grafana 2. 快速试用2.1 Prometheus 普罗 米修斯2.2 Prometheus 配置文件2.3 Grafana 2. 使用 Docker-Compose脚本部署监控服务3. Grafana 配置3.1 配置数据源 Prometheus3.2 使用模板ID 配置监控模板3.3 使用…

【SpringBoot】怎么在一个大的SpringBoot项目中创建多个小的SpringBoot项目,从而形成子父依赖

父子项目工程创建 步骤 先创建父项目 具体操作步骤请看本文章&#xff1a;使用maven工程创建spring boot项目 创建子项目 file- project structure module–new module 剩下步骤请看创建父工程时的操作使用maven工程创建spring boot项目 应用 确认即可 之后创建启动类…

Kafka篇:Kafka搭建、使用、及Flink整合Kafka文档

一、Kafka搭建 1、上传并解压改名 tar -xvf kafka_2.11-1.0.0.tgz mv kafka_2.11-1.0.0 kafka-1.0.0 2、配置环境变量 vim /etc/profile export KAFKA_HOME/usr/local/soft/kafka-1.0.0 export PATH$PATH:$KAFKA_HOME/bin source /etc/profile &#xff08;使环境变量生效…