统一响应,自定义校验器,自定义异常,统一异常处理器

news2025/1/15 16:32:58

文章目录

    • 1.基本准备(构建一个SpringBoot模块)
        • 1.在A_universal_solution模块下创建新的子模块unified-processing
        • 2.pom.xml引入基本依赖
        • 3.编写springboot启动类
        • 4.启动测试
    • 2.统一响应处理
        • 1.首先定义一个响应枚举类 RespBeanEnum.java 每个枚举对象都有code和message
        • 2.然后定义一个响应的Bean RespBean.java ,可以调用响应枚举类,进行响应
        • 3.测试使用
          • 1.目录结构
          • 2.ResponseTest.java
          • 3.浏览器测试
            • 1.成功响应,不携带数据。
            • 2.成功响应,携带数据。
            • 3.失败响应,不携带数据。
            • 4.失败响应,携带数据。
            • 5.测试withData方法。
            • 6.测试withMessage方法。
    • 3.自定义校验器
        • 1.首先编写一个Bean测试使用,LoginVo.java
        • 2.需求分析
          • 自定义校验器来校验手机号和密码
        • 3.通用校验器模板
          • 1.定义通用校验器接口 GenericValidatorInterface.java
          • 2.自定义校验注解 GenericValidation.java
          • 3.通用校验器实现类 GenericValidatorImpl.java
          • 4.使用方式
            • 1.需求分析
            • 2.将模板复制一份,放到validator包下,准备进行修改
            • 3.要校验的字段为Integer类型,也就是修改value类型
            • 4.注解中的value是int数组类型,也就是修改annotationValue的类型
            • 5.修改三个类的名字前缀为Test,直接修改然后alter +enter 让IDEA自动修改
            • 6.TestValidatorImpl.java编写校验逻辑
            • 7.修改LoginVo.java 添加测试校验字段
            • 8.编写controller加上@Valid字段进行校验
            • 9.测试
    • 4.统一异常处理器整合自定义校验器
        • 1.编写自定义异常携带响应枚举对象 CustomException.java
        • 2.编写全局异常处理器 GlobalExceptionHandler.java
        • 3.最佳实践
          • 1.当需要响应error时直接抛出自定义异常对象,指定响应枚举对象
          • 2.此时当出现参数绑定异常时也会交给统一异常处理解决
          • 3.当出现其他异常时,就会响应服务端异常,控制台也会打印错误信息

1.基本准备(构建一个SpringBoot模块)

1.在A_universal_solution模块下创建新的子模块unified-processing

image-20240506125441280

2.pom.xml引入基本依赖
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 继承spring-boot父模块 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- 如果交给父模块统一管理,但是又要继承springboot的父模块,就必须加这个 -->
    </parent>

    <artifactId>unified-processing</artifactId>
    <packaging>jar</packaging>

    <name>unified-processing</name>
    <url>http://maven.apache.org</url>


    <!-- 解决java: -source 1.5 中不支持 diamond 运算符 问题 -->
    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>


    <dependencies>
        <!--validation 参数校验-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.4.5</version>
        </dependency>

        <!-- springboot两个常规配置 -->
        <!-- spring-boot-starter-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- spring-boot-starter-test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- lombok也是常规配置 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- jupiter测试 -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.7.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <!-- maven打包插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3.编写springboot启动类
package com.sun.solution;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/5/6 13:00
 * @Version 1.0
 */
@SpringBootApplication
public class UnifiedApplication {
    public static void main(String[] args) {
        SpringApplication.run(UnifiedApplication.class, args);
    }
}

4.启动测试

image-20240506130251247

2.统一响应处理

1.首先定义一个响应枚举类 RespBeanEnum.java 每个枚举对象都有code和message
package com.sxs.seckill.vo;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

/**
 * Description: 响应枚举类
 *
 * @Author sun
 * @Create 2024/5/5 15:15
 * @Version 1.0
 */

@Getter
@AllArgsConstructor
@ToString
public enum RespBeanEnum {
    // 通用
    SUCCESS(200, "SUCCESS"),
    ERROR(500, "服务端异常"),
    //登录模块
    LOGIN_ERROR(500210, "用户名或者密码错误"),
    MOBILE_ERROR(500211, "手机号码格式不正确"),
    BING_ERROR(500212, "参数绑定异常"),
    MOBILE_NOT_EXIST(500213, "手机号码不存在"),
    PASSWORD_UPDATE_FAIL(500214, "更新密码失败");
    //其他模块。。。

    // 响应码和响应信息
    private final Integer code;
    private final String message;
}

2.然后定义一个响应的Bean RespBean.java ,可以调用响应枚举类,进行响应
package com.sxs.seckill.vo;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 通用响应数据封装类。
 * 提供了构造函数和静态方法来创建响应对象,支持链式调用来设置属性。
 */
@Getter
@Setter
@Accessors(chain = true) // 支持链式调用
public class RespBean {
    private long code;
    private String message;
    private Object data;

    /**
     * 默认构造函数。
     */
    public RespBean() {}

    /**
     * 构造函数,初始化响应码和消息。
     * @param code 响应码。
     * @param message 响应消息。
     */
    public RespBean(long code, String message) {
        this.code = code;
        this.message = message;
    }

    /**
     * 构造函数,初始化响应码、消息和数据。
     * @param code 响应码。
     * @param message 响应消息。
     * @param data 响应数据。
     */
    public RespBean(long code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 成功响应,携带数据。
     * @param data 响应数据。
     * @return 生成的成功响应对象。
     */
    public static RespBean success(Object data) {
        return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), data);
    }

    /**
     * 成功响应,不携带数据。
     * @return 生成的成功响应对象。
     */
    public static RespBean success() {
        return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), null);
    }

    /**
     * 错误响应,只携带错误枚举。
     * @param respBeanEnum 错误枚举,包含错误码和消息。
     * @return 生成的错误响应对象。
     */
    public static RespBean error(RespBeanEnum respBeanEnum) {
        return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), null);
    }

    /**
     * 错误响应,携带错误枚举和额外数据。
     * @param respBeanEnum 错误枚举,包含错误码和消息。
     * @param data 额外数据。
     * @return 生成的错误响应对象。
     */
    public static RespBean error(RespBeanEnum respBeanEnum, Object data) {
        return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), data);
    }

    /**
     * 设置响应数据。
     * @param data 响应数据。
     * @return 当前对象,支持链式调用。
     */
    public RespBean withData(Object data) {
        this.data = data;
        return this;
    }

    /**
     * 设置响应消息。
     * @param message 响应消息。
     * @return 当前对象,支持链式调用。
     */
    public RespBean withMessage(String message) {
        this.message = message;
        return this;
    }
}

3.测试使用
1.目录结构

image-20240506131857665

2.ResponseTest.java
package com.sun.solution.conroller;

import com.sun.solution.unified_response_processing.RespBean;
import com.sun.solution.unified_response_processing.RespBeanEnum;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/5/6 13:07
 * @Version 1.0
 */
@RestController
public class ResponseTest {
    /**
     * 成功响应,不携带数据。
     *
     * @return
     */
    @RequestMapping("/success1")
    public RespBean success1() {
        return RespBean.success();
    }

    /**
     * 成功响应,携带数据。
     *
     * @return
     */
    @RequestMapping("/success2")
    public RespBean success2() {
        return RespBean.success("成功响应,携带数据。");
    }


    /**
     * 失败响应,不携带数据。
     *
     * @return
     */
    @RequestMapping("/error1")
    public RespBean error1() {
        return RespBean.error(RespBeanEnum.ERROR);
    }

    /**
     * 失败响应,携带数据。
     *
     * @return
     */
    @RequestMapping("/error2")
    public RespBean error2() {
        return RespBean.error(RespBeanEnum.ERROR, "失败响应,携带数据。");
    }

    /**
     * 测试withData方法
     *
     * @return
     */
    @RequestMapping("/withData")
    public RespBean withData() {
        return RespBean.error(RespBeanEnum.ERROR).withData("测试withData方法");
    }

    /**
     * 测试withMessage方法
     *
     * @return
     */
    @RequestMapping("/withMessage")
    public RespBean withMessage() {
        return RespBean.error(RespBeanEnum.ERROR).withMessage("测试withMessage方法");
    }

}

3.浏览器测试
1.成功响应,不携带数据。

image-20240506132159483

2.成功响应,携带数据。

image-20240506132322584

3.失败响应,不携带数据。

image-20240506132344487

4.失败响应,携带数据。

image-20240506132403115

5.测试withData方法。

image-20240506132427551

6.测试withMessage方法。

image-20240506132447397

3.自定义校验器

1.首先编写一个Bean测试使用,LoginVo.java
package com.sun.solution.vo;

import lombok.Data;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/5/6 13:29
 * @Version 1.0
 */
@Data
public class LoginVo {
    private String mobile;
    private String password;
}
2.需求分析
自定义校验器来校验手机号和密码
3.通用校验器模板
1.定义通用校验器接口 GenericValidatorInterface.java
package com.sun.solution.validator;

/**
 * Description: 通用校验器接口,用于重新定义校验方法,使其更加灵活
 *
 * @Author sun
 * @Create 2024/5/6 13:34
 * @Version 1.0
 */

public interface GenericValidatorInterface {
    /**
     * 校验接口
     * @param value 待校验的值,根据情况自定义类型
     * @param annotationValue 注解中的value值,根据情况自定义类型
     * @param required 是否必填
     * @return
     */
    boolean isValid(String value, String annotationValue, boolean required);
}

2.自定义校验注解 GenericValidation.java
package com.sun.solution.validator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * Description: 自定义校验注解
 *
 * @Author sun
 * @Create 2024/5/6 13:38
 * @Version 1.0
 */
@Documented
@Constraint(validatedBy = GenericValidatorImpl.class) // 1.这里是校验器的实现类
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface GenericValidation {
    // 2.这里是注解的属性
    // message是校验失败时的提示信息
    String message() default "校验失败!";
    // value是注解的值,可以根据情况自定义类型,类型改变则校验器也需要改变
    String value() default "";
    // required是是否必填
    boolean required() default true;

    // 下面这两个属性必须添加,是默认属性
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

3.通用校验器实现类 GenericValidatorImpl.java
package com.sun.solution.genericvalidator;

import org.springframework.util.StringUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * Description: 通用校验器实现类,ConstraintValidator<TestValidation, String>中的两个参数分别是注解和校验的值类型
 *
 * @Author sun
 * @Create 2024/5/6 13:42
 * @Version 1.0
 */
public class GenericValidatorImpl implements ConstraintValidator<GenericValidation, String>, GenericValidatorInterface {

    // 注解中的value值,根据情况自定义类型
    private String annotationValue;
    // 注解中的required值,表示是否必填
    private boolean required;

    /**
     * 初始化方法,获取注解中的value值和required值
     * @param annotation
     */
    @Override
    public void initialize(GenericValidation annotation) {
        this.annotationValue = annotation.value();
        this.required = annotation.required();
    }

    /**
     * 初始的校验方法
     * @param value
     * @param context
     * @return
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return isValid(value, annotationValue, required);
    }

    /**
     * 增强的校验方法
     * @param value 待校验的值
     * @param annotationValue 注解中的value值,根据情况自定义类型
     * @param required 是否必填
     * @return
     */
    @Override
    public boolean isValid(String value, String annotationValue, boolean required) {
        // 校验逻辑编写,根据三个参数进行校验
        return false;
    }
}

4.使用方式
1.需求分析

假设,要校验的字段类型是Integer类型,注解中的value是int数组类型

2.将模板复制一份,放到validator包下,准备进行修改

image-20240506142134488

3.要校验的字段为Integer类型,也就是修改value类型

GenericValidatorInterface.java

image-20240506142712265

GenericValidatorImpl.java

image-20240506142756701

4.注解中的value是int数组类型,也就是修改annotationValue的类型

GenericValidation.java

image-20240506143335834

GenericValidatorImpl.java

image-20240506143407645

GenericValidatorInterface.java

image-20240506143434441

5.修改三个类的名字前缀为Test,直接修改然后alter +enter 让IDEA自动修改

image-20240506143656011

6.TestValidatorImpl.java编写校验逻辑
    /**
     * 增强的校验方法
     * @param value 待校验的值
     * @param annotationValue 注解中的value值,根据情况自定义类型
     * @param required 是否必填
     * @return
     */
    @Override
    public boolean isValid(Integer value, int[] annotationValue, boolean required) {
        // 如果不是必填项,且值为空,则直接返回true
        if (!required && value == null) {
            return true;
        }
        // 如果是必填项,且值为空,则直接返回false
        if (required && value == null) {
            return false;
        }
        // 如果注解中的value值不为空,且待校验的值不在value值中,则返回false
        if (annotationValue.length > 0) {
            for (int i : annotationValue) {
                if (value == i) {
                    return true;
                }
            }
            return false;
        }
        return true;
    }
7.修改LoginVo.java 添加测试校验字段
package com.sun.solution.vo;

import com.sun.solution.validator.TestValidation;
import lombok.Data;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/5/6 13:29
 * @Version 1.0
 */
@Data
public class LoginVo {
    private String mobile;
    private String password;
    @TestValidation(value = {1, 2, 3}, required = true)
    private Integer test;
}
8.编写controller加上@Valid字段进行校验
package com.sun.solution.conroller;

import com.sun.solution.unified_response_processing.RespBean;
import com.sun.solution.vo.LoginVo;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/5/6 14:56
 * @Version 1.0
 */
@RestController
public class ValidationTest {
    @PostMapping("/test")
    public RespBean test(@Valid @RequestBody LoginVo loginVo) {
        return RespBean.success("success!");
    }
}

9.测试

image-20240506150821623

image-20240506150835102

4.统一异常处理器整合自定义校验器

1.编写自定义异常携带响应枚举对象 CustomException.java
package com.sun.solution.exception;

import com.sun.solution.unified_response_processing.RespBeanEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Description: 自定义异常类,具有响应枚举的属性。
 *
 * @Author sun
 * @Create 2024/5/6 15:15
 * @Version 1.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CustomException extends RuntimeException{
    private RespBeanEnum respBeanEnum;
}

2.编写全局异常处理器 GlobalExceptionHandler.java
package com.sun.solution.exception;

import com.sun.solution.unified_response_processing.RespBean;
import com.sun.solution.unified_response_processing.RespBeanEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * Description:
 *
 * @Author sun
 * @Create 2024/5/6 15:16
 * @Version 1.0
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    // 处理所有的异常
    @ExceptionHandler(Exception.class)
    public RespBean exceptionHandler(Exception e) {
        // 日志记录异常信息及堆栈
        log.error("Exception caught: ", e); 
        
        // 如果得到的是自定义异常的对象,那么直接返回这个异常的响应枚举类信息
        if (e instanceof CustomException) {
            CustomException ex = (CustomException) e;
            return RespBean.error(ex.getRespBeanEnum());
        } else if (e instanceof BindException) {
            // 如果是绑定异常,就获取绑定异常的message信息,返回给前端
            // 需要获取改异常 BindException,进行打印
            BindException ex = (BindException) e;
            // 获取绑定异常的信息
            RespBean respBean = RespBean.error(RespBeanEnum.BING_ERROR).withMessage("参数校验异常:" +
                    ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
            return respBean;
        }
        
        // 如果不是自定义异常,那么返回服务端异常
        return RespBean.error(RespBeanEnum.ERROR);
    }
}

3.最佳实践
1.当需要响应error时直接抛出自定义异常对象,指定响应枚举对象

image-20240506153836780

image-20240506153848112

2.此时当出现参数绑定异常时也会交给统一异常处理解决

image-20240506154042389

3.当出现其他异常时,就会响应服务端异常,控制台也会打印错误信息

image-20240506154219232

image-20240506154225690

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

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

相关文章

全息之镜,未来的眼镜

全息之镜&#xff0c;作为未来眼镜的一种设想和展望&#xff0c;凭借其独特的全息技术&#xff0c;将在未来带来全新的视觉体验和应用场景。以下是关于全息之镜未来的详细分析和展望&#xff1a; 一、技术原理与特点 全息之镜利用全息技术&#xff0c;通过干涉、衍射和折射等…

Arthas调优工具使用

1&#xff0c;服务器端下载 curl -O https://arthas.aliyun.com/arthas-boot.jar 2&#xff0c;服务器端启动 java -jar arthas-boot.jar 选定要绑定的Java进程ID 3&#xff0c;本地idea安装Arthas idea 4&#xff0c;选定方法右键trace,生成命令 trace com.xxx.xxx.xxx.vouche…

6_5 test

Lucene 存储引擎 https://www.cnblogs.com/tech-lee/p/15225276.html\ 规范 问问题的技巧 提问者&#xff1a;要实现怎样的目标&#xff1f;自己计划是如何实现这个目标的&#xff1f;问题出现在哪个环节&#xff1f;自己为了解决这个问题&#xff0c;已经做了哪些尝试和工…

json和axion结合

目录 java中使用JSON对象 在pom.xml中导入依赖 使用 public static String toJSONString(Object object)把自定义对象变成JSON对象 json和axios综合案例 使用的过滤器 前端代码 响应和请求都是普通字符串 和 请求时普通字符串&#xff0c;响应是json字符串 响应的数据是…

【kubeflow文档】Kubeflow Training Operator

What is Training Operator Training Operator是一个Kubernetes原生项目&#xff0c;用于对使用各种ML框架&#xff08;如PyTorch、TensorFlow、XGBoost等&#xff09;创建的机器学习&#xff08;ML&#xff09;模型进行微调和可扩展的分布式训练。 用户可以将HuggingFace、Dee…

HarmonyOS App开发造轮子--自定义圆形图片

思路&#xff1a; 1、对比之前自己在其他程序开发中自定义组件的思路&#xff0c;首先寻找父组件Image和Component相关的Api&#xff0c;看看是否具备OnDraw方法。 2、了解Canvas相关Api操作&#xff0c;特别是涉及到位图的操作。 通过翻阅大量资料&#xff0c;发现了两个关…

【漏洞复现】Apache OFBiz 路径遍历导致RCE漏洞(CVE-2024-36104)

0x01 产品简介 Apache OFBiz是一个电子商务平台&#xff0c;用于构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类应用系统。是美国阿帕奇(Apache)基金会的一套企业资源计划(ERP)系统。该系统提供了一整套基于Java的Web应用程序组件和工具。 0x02 …

德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第五周) - Transformer

Transformer 1. 注意力机制 在语言建模中&#xff0c;注意力(attention)是一个关键机制&#xff0c;用于在给定上下文中访问相关信息以进行预测。注意力机制允许模型根据输入上下文中的重要信息来加权关注不同的部分&#xff0c;并根据其重要性来决定对不同部分的关注程度。 …

C#操作MySQL从入门到精通(10)——对查询数据进行通配符过滤

前言 我们有时候需要查询数据,并且这个数据包含某个字符串,这时候我们再使用where就无法实现了,所以mysql中提供了一种模糊查询机制,通过Like关键字来实现,下面进行详细介绍: 本次查询的表中数据如下: 1、使用(%)通配符 %通配符的作用是,表示任意字符出现任意次数…

C++ list链表的使用和简单模拟实现

目录 前言 1. list的简介 2.list讲解和模拟实现 2.1 默认构造函数和push_back函数 2.2 迭代器实现 2.2.1 非const正向迭代器 2.2.2 const正向迭代器 2.2.3 反向迭代器 2.3 插入删除函数 2.3.1 insert和erase 2.3.2 push_back pop_back push_front pop_front 2.4 构…

QT+FFmpeg+Windows开发环境搭建(加薪点)

01、Windows 环境搭建 FFMPEG官网:http://ffmpeg.org/ 02、下载4.2.1版本源码 源码:https://ffmpeg.org/releases/ffmpeg-4.2.1.tar.bz2 03、下载4.2.1编译好的文件 下载已经编译好的FFMPEG)(迅雷下载很快) 网址:https://ffmpeg.zeranoe.com/builds/ 32位下载地址:(迅雷…

这家公司的39亿存款,无法收回了?

新闻提要 4日晚间&#xff0c;亿利洁能发布公告称&#xff0c;亿利财务公司对于公司存放在亿利财务公司的 39.06 亿元货币资金的用途主要是向亿利集团及其关联方发放贷款&#xff0c;近日公司获悉相关贷款已被划分为次级贷款&#xff08;不良贷款的一种&#xff09;&#xff0…

重大变化,2024软考!

根据官方发布的2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试安排&#xff0c;2024年软考上、下半年开考科目有着巨大变化&#xff0c;我为大家整理了相关信息&#xff0c;大家可以看看&#xff01; &#x1f3af;2024年上半年&#xff1a;5月25日&am…

特征工程及python实现

一、特征构建 概述 从原始数据中构建新的特征&#xff0c;一般需要根据业务分析&#xff0c;生成能更好体现业务特性的新特征&#xff0c;这些新特征要与目标关系紧密&#xff0c;能提升模型表现或更好地解释模型。 方法 时间周期&#xff1a;不同的时间切片长度&#xff0…

Linux信号大揭秘-从中断到控制进程,一步步掌握进程通信利器!

在Linux环境下&#xff0c;信号(Signal)是一种软件中断&#xff0c;用于通知进程发生了某些重要事件。无论你是在编写命令行工具、服务程序&#xff0c;还是开发图形界面应用&#xff0c;都离不开对信号的处理。本文将全面解析信号的工作原理&#xff0c;并通过实例代码让你彻底…

实用软件分享---简单菜谱 0.3版本 几千种美食(安卓)

专栏介绍:本专栏主要分享一些实用的软件(Po Jie版); 声明1:软件不保证时效性;只能保证在写本文时,该软件是可用的;不保证后续时间该软件能一直正常运行;不保证没有bug;如果软件不可用了,我知道后会第一时间在题目上注明(已失效)。介意者请勿订阅。 声明2:本专栏的…

重生之 SpringBoot3 入门保姆级学习(14、内容协商基础简介)

重生之 SpringBoot3 入门保姆级学习&#xff08;14、内容协商基础简介&#xff09; 3.3 内容协商3.3.1 基础简介3.3.2 演示效果 3.3 内容协商 3.3.1 基础简介 默认规则 基于请求头的内容协商&#xff08;默认开启&#xff09; 客户端向服务器发送请求&#xff0c;携带 HTTP 标…

大归纳!!教你使用<string.h>的字符函数与字符串函数!!☑

这篇博客为你归纳了所有的字符函数和最常用的字符串函数&#xff0c;以及对应的模拟实现&#xff01;&#xff01;你可以直接循着目录跳到你需要的段落哦&#xff01;&#xff01;&#x1f60d; 目录 字符函数 字符分类 字符判断函数 islower——判断小写字母 isupper——…

上位机图像处理和嵌入式模块部署(f407 mcu中的udp server开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 既然lwip已经port到407上面了&#xff0c;接下来其实就可以做一些测试了。本身lwip支持tcp、udp&#xff0c;也支持client和server&#xff0c;既然…

Qt信号槽与函数直接调用性能对比

1. 测试方法 定义一个类Recv&#xff0c;其中包含一个成员变量num和一个成员函数add()&#xff0c;add()实现num的递增。 另一个类Send通过信号槽或直接调用的方法调用Recv的add函数。 单独开一个线程Watcher&#xff0c;每秒计算num变量的增长数值&#xff0c;作为add函数被调…