带你搞懂@Valid和@Validated的区别
前言
有参数传递的地方都少不了参数校验。在实际开发过程中,参数校验是保证程序健壮性的重要环节,前端的参数校验是为了用户体验,后端的参数校验是为了安全。试想一下,如果在 Controller 层中没有经过任何校验的参数通过 Service层、Dao层一路来到了数据库就可能导致严重的后果,最好的结果是查不出数据。严重一点就是报错,如果这些没有被校验的参数中包含了恶意代码,那就可能导致更严重的后果。因此,对于请求参数,一般上都需要进行参数合法性校验的,参数校验是确保数据完整性和一致性的重要手段。日常开发过程中,经常遇到大量的参数进行校验, 在业务中还要抛出异常等校验信息, 在代码中相当冗长, 充满了 if-else 这种校验代码, 代码不够优雅。@Valid、@Validated 是 Spring Boot 中用于参数校验的两个核心注解,本文将详细介绍这两个注解的用法、区别以及代码样例。
@Valid注解
功能介绍
@Valid 是 Java EE 提供的标准注解,它是 JSR 303 规范的一部分。在 Spring Boot 项目中,主要用于触发参数校验,确保请求参数的合法性。Javax.validation 是 Spring 集成自带的一个参数校验接口,可通过添加注解来设置校验条件。若是 Spring Boot 项目,就不用引入了,它已经存在于最核心的 web 开发包里面。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.0.5.RELEASE</version>
</dependency>
如若不是 Spring Boot 项目,那么引入下面依赖即可:
<dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>x.y.z</version>
</dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>z.y.z</version>
</dependency>
使用场景
@Valid 可以用于方法参数、构造函数、方法参数和成员属性上。它主要用于嵌套校验,即对于对象中的属性值(可能是另一个对象)进行校验。例如:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SysUser {@NotBlank(message = "请输入姓名")@Length(message = "名称不能超过个 {max} 字符", max = 10)private String name;@NotNull(message = "请输入年龄")@Range(message = "年龄范围为 {min} 到 {max} 岁之间", min = 1, max = 100)private Integer age;@NotNull(message = "请选择性别")private Integer sex;private String phone;
}
既然验证,那么就肯定会有验证结果,所以我们需要用一个东西来存放验证结果,做法也很简单,在参数直接添加一个BindingResult,具体如下:
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;@RestControoler
@RequestMapping("/sysUser")
public class SysUserController {@PostMapp("/add")public String addUser(@ResuestBody @Valid SysUser sysUser BindingResult bindingResult){// 所有字段是否验证通过,true-数据有误,false-数据无误if (bindingResult.hasErrors()){// 有误,则返回第一条错误信息return bindingResult.getAllErrors().get(0).getDefaultMessage();}retrun "操作成功!";}
}
在上述代码中,在 SysUserController 中,addUser 方法使用了 @Valid
注解对传入的 SysUser 对象进行校验,并使用 BindingResult 捕获校验错误。
@Validated注解
功能介绍
@Validated 是 Spring 框架特有的注解,属于 Spring 的一部分,也是 JSR 303 的一个变种。简单来说,@Validated 可以说是 @Valid 注解的一个升级版。它提供了一些 @Valid 所没有的额外功能,比如分组验证。@Validated注解可以用在类、方法和方法参数上,但不能用于成员属性。
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Person {@NotNull(message = "id添加时可以为空,更新时不能为空", groups = {UpdateGroup.class})private Integer id;@NotBlank(message = "名字不能为空", groups = {UpdateGroup.class, AddGroup.class})@Size(min = 6, max = 12, message = "名字的长度在6到12之间", groups = {UpdateGroup.class, AddGroup.class})private String username;@NotNull(message = "年龄不能为空", groups = {UpdateGroup.class, AddGroup.class})@Min(value = 20, message = "最小年龄要大于20", groups = {UpdateGroup.class, AddGroup.class})private Integer age;
}
使用场景
@Validated 注解主要用于支持分组验证,可以更细致地控制验证过程。一般在对同一个对象进行保存或修改时,会使用同一个类作为入参。那么在创建时,就不需要校验id,更新时则需要校验用户id,这个时候就需要用到分组校验了。分组验证是为了在不同的验证场景下能够对对象的属性进行灵活地验证,从而提高验证的精细度和适用性。
/*** 用于创建时指定的分组*/
public interface CreationGroup {
}/*** 用于更新时指定的分组*/
public interface UpdateGroup {
}@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SysUser {@NotBlank(message="id添加时可以为空,更新时不能为空", groups={UpdateGroup.class})private String id;@NotBlank(message="名字不能为空", groups={CreationGroup.class, UpdateGroup.class})@Size(min=6, max=12, message="名字的长度在6到12之间", groups={CreationGroup.class, UpdateGroup.class})private String name;@NotNull(message="年龄不能为空", groups={CreationGroup.class, UpdateGroup.class})@Min(value = 1, message = "年龄不能小于1", groups=ValidationGroups.Insert.class)private int age;
}
在上述代码中,我们定义了一个 CreationGroup、UpdateGroup 两个接口,用于分组验证。SysUser 类中的 id 属性在 Update 分组下必填,而 age 属性在 Insert 分组下必填且不能小于1。
@RestController
public class SysUserController {@PostMapping("/insert")public String insertUser(@Validated(value=CreationGroup.class) @RequestBody SysUser sysUser, BindingResult bindingResult) {if (bindingResult.hasErrors()) {return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();}return "插入成功";}@PostMapping("/update")public String updateUser(@Validated(value=UpdateGroup.class) @RequestBody SysUser sysUser, BindingResult bindingResult) {if (bindingResult.hasErrors()) {return "参数校验失败: " + bindingResult.getAllErrors().get(0).getDefaultMessage();}return "更新成功";}
}
在 SysUserController 中,insertUser 方法使用 @Validated(value=CreationGroup.class)
对传入的 SysUser 对象进行 Insert 分组的校验,而 updateUser 方法则使用 @Validated(value=UpdateGroup.class)
进行 Update 分组的校验。对于定义分组有两点要特别注意:
- 定义分组必须使用接口。
- 要校验字段上必须加上分组,分组只对指定分组生效,不加分组不校验。
异常统一处理
我们可以看到,在使用 @Valid 进行验证时,需要用一个对象去接收校验结果,最后根据校验结果判断,从而提示用户。现在,我们去掉方法参数上的 @Valid 注解和其配对的 BindingResult 对象,然后再校验的对象前面添加上 @Validated 注解。
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;@RestControoler
@RequestMapping("/sysUser")
public class SysUserController {@PostMapp("/add")public String addUser(@ResuestBody @Validated SysUser){// 所有字段是否验证通过,true-数据有误,false-数据无误if (bindingResult.hasErrors()){// 有误,则返回第一条错误信息return bindingResult.getAllErrors().get(0).getDefaultMessage();}retrun "操作成功!";}
}
这个时候若是请求,可以看到程序报异常了。那么,从这里可以得知,当数据存在校验不通过的时候,程序就会抛出 org.springframework.validation.BindException
的异常。在实际开发的过程中,肯定不能讲异常直接展示给用户,而是给能看懂的提示。于是,不妨可以通过捕获异常的方式,将该异常进行捕获。首先创建一个校验异常捕获类 ValidExceptionHandler
,然后加上 @RestControllerAdvice 注解,该注解表示会捕获所有 @Controller 标记类的异常,并在异常处理后返回以 JSON 或字符串的格式响应前端。在异常捕捉到后,同上面的 @valid 校验一样,只返回第一个错误提示。
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.*;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import java.util.List;@ControllerAdvice
public class ValidatedExceptionHandler {/*** 处理@Validated参数校验失败异常*/@ResponseBody@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(MethodArgumentNotValidException.class)public Result<String> exceptionHandler(MethodArgumentNotValidException exception) {BindingResult result = exception.getBindingResult();StringBuilder stringBuilder = new StringBuilder();if (result.hasErrors()) {List<ObjectError> errors = result.getAllErrors();errors.forEach(p -> {FieldError fieldError = (FieldError) p;stringBuilder.append(fieldError.getDefaultMessage());});}return Result.error(stringBuilder.toString());}}
知识拓展
@Valid 和 @Validated 区别
@Validated 和 @Valid 在检验参数符合规范的功能上基本一致,两者都可以对数据进行校验,在校验字段上加上规则注解(@NotNull, @NotEmpty等)都可以对 @Valid 和 @Validated 生效。只不过 validated 是 Spring Validation 验证框架对参数的验证机制,而 valid 是 javax 提供的参数验证机制。先看下两者的源码:
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Valid {
}@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {Class<?>[] value() default {};
}
- 适用场景:@Valid 适用于使用Hibernate validation框架的情况,而 @Validated 则适用于使用Spring Validator校验机制的场景。因此,选择合适的注解要根据实际使用的框架来决定。
- 验证方式:@Valid 可以进行嵌套验证,这意味着它可以对复合对象进行深层次的验证。而 @Validated 则不具备嵌套验证的功能,它只能对单一对象进行校验。因此,在需要进行复合对象验证时,应选择 @Valid 注解。
- 使用范围:@Valid 可以用在方法、构造函数、方法参数和成员属性(field)上,支持在多种场合下进行参数校验。而 @Validated 则主要用于类、方法和方法参数上,不能用于成员属性(field)。因此,在使用成员属性(field)进行校验时,应选择 @Valid 注解。
- 自定义校验规则:@Validated 提供了分组功能,可以在参数验证时根据不同的分组采用不同的验证机制。这意味着可以根据实际需求将参数分为不同的组,并为每组设置特定的校验规则。而 @Valid 注解则没有分组功能,其校验规则较为固定。因此,在需要自定义校验规则时,应选择@Validated注解。
- 校验结果:@Valid 进行校验的时候,需要用 BindingResult 来做一个校验结果接收。当校验不通过的时候,如果手动不 return ,则并不会阻止程序的执行。@Validated 进行校验的时候,当校验不通过的时候,程序会抛出400异常,阻止方法中的代码执行,这时需要再写一个全局校验异常捕获处理类,然后返回校验提示。
总体来说,@Validated 使用起来要比 @Valid 方便一些,它可以帮我们节省一定的代码量,并且使得方法看上去更加的简洁。
参数校验常用注解
值校验
注解 | 说明 | 示例 |
---|---|---|
@Null | 任意类型,被注解的元素必须为null | @Null(message = “人数必须为null”) private Integer num; |
@NotNull | 任意类型,被注解的元素必须不为null | @NotNull(message = “人数不能为null”) private Integer num; |
@NotBlank | 只能作用于字符串,验证注解的元素值不为空。 字符串长度必须大于0,至少包含一个非空字符串 | @NotBlank(message = “姓名不能为空”) private String name; |
@NotEmpty | 验证注解的元素值不为null且不为空。 字符串长度必须大于0,空字符串(“ ”)可以通过校验 | @NotEmpty(message = “组织部门不能为空”) private List<String> userList; |
@AssertTrue | 被注解的元素必须为true,并且类型为boolean | @AssertTrue(message = “状态必须为true”) private boolean status; |
@AssertFalse | 被注解的元素必须为false,并且类型为boolean | @AssertFalse(message = “状态必须为false”) private boolean status; |
@Positive | 被注解的元素必须为正数 | @Negative(message = “金额必须是正数或0”) private BigDecimal amount; |
@PositiveOrZero | 被注解的元素必须为正数或 0 | @Negative(message = “金额必须是正数或0”) private BigDecimal amount; |
@Negative | 被注解的元素必须为负数 | @Negative(message = “金额必须是负数”) private BigDecimal amount; |
@NegativeOrZero | 被注解的元素必须为负数或 0 | @Negative(message = “金额必须是负数或0”) private BigDecimal amount; |
范围校验
注解 | 说明 | 示例 |
---|---|---|
@Min | 被注解的元素其值必须大于等于最小值 | @Min(value = 18, message = “必须大于等于18岁”) private int age; |
@Max | 被注解的元素其值必须小于等于最小值 | @Max(value = 120, message = “必须小于等于120岁”) private int age; |
@DecimalMin | 验证注解的元素值大于等于指定的value值,并且类型为BigDecimal | @DecimalMin(value = “1”, message = “必须大于等于1”) private BigDecimal money; |
@DecimalMax | 验证注解的元素值小于等于指定的value值 ,并且类型为BigDecimal | @DecimalMax(value = “10”, message = “必须小于等于10”) private BigDecimal money; |
@Range | 验证注解的元素值在最小值和最大值之间 | @Range(max = 80, min = 18, message = “必须大于等于18或小于等于80”) private int age; |
@Past | 被注解的元素必须为过去的一个时间 | @Past(message = “必须为过去的时间”) private Date createDate; |
@PastOrPresent | 被注解的元素必须为当前时间或之前的时间 | @PastOrPresent(message = “必须为当前或过去的时间”) private Date createDate; |
@Future | 被注解的元素必须为未来的一个时间 | @Future(message = “必须为未来的时间”) private Date createDate; |
@FutureOrPresent | 被注解的元素必须为当前或之后的时间 | @FutureOrPresent(message = “必须为当前或未来的时间”) private Date createDate; |
长度校验
注解 | 说明 | 示例 |
---|---|---|
@Size | 被注解的元素的长度必须在指定范围内 | @Size(max = 11, min = 7, message = “长度必须大于等于7或小于等于11”) private String mobile; |
@Length | 验证注解的元素值长度在min和max区间内 ,并且类型为String | @Length(max = 11, min = 7, message = “长度必须大于等于7或小于等于11”) private String mobile; |
格式校验
注解 | 说明 | 示例 |
---|---|---|
@Digits | 验证注解的元素值的整数位数和小数位数上限 | @Digits(integer=3,fraction = 2,message = “整数位上限为3位,小数位上限为2位”) private BigDecimal money; |
@Pattern | 被注解的元素必须符合指定的正则表达式,并且类型为String | @Pattern(regexp = “^1[1-9]\d{9}$”, message = “手机号格式错误”) private String mobile; |
被注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式 | @Email(message = “必须是邮箱”) private String email; | |
@Valid | 指定递归验证关联的对象。 | @Valid private UserDto userDto; |
@URL | 被注解的元素必须是一个有效的url地址,并且类型为String | @URL(message = “无效的url地址”) private String url; |
小结
@Valid、@Validated 在 Spring Boot 的参数校验中扮演着重要角色,在实际开发中,选择合适的注解进行参数校验需要考虑多个因素,了解注解的使用限制和特点也有助于我们更好地规避潜在的问题和提高代码的可维护性。总之,了解并正确使用 @Valid 和 @Validated 注解是保障程序健壮性的关键之一。掌握这两个注解的用法和区别,可以帮助开发者更灵活地进行参数校验,确保数据的完整性和一致性,从而提高程序的稳定性和可靠性。
相关文章:
带你搞懂@Valid和@Validated的区别
前言 有参数传递的地方都少不了参数校验。在实际开发过程中,参数校验是保证程序健壮性的重要环节,前端的参数校验是为了用户体验,后端的参数校验是为了安全。试想一下,如果在 Controller 层中没有经过任何校验的参数通过 Service层…...
大数据hadoop小文件处理方案
Hadoop处理小文件问题的解决方案可分为存储优化、处理优化和架构优化三个维度,以下是综合技术方案及实施要点: 一、存储层优化方案 1.文件合并技术 离线合并:使用hadoop fs -getmerge命令将多个小文件合并为大文件并重新上传; MapReduce合并:开发专用MR…...
安装NASM
安装NASM 注意:这篇文章在librdkafka安装系列,不需要参考,仅为了记录而写,请不要参考,后续编译openssl的时候,可以使用参数no-asm,不影响整个的编译步骤。这里主要作为记录帖子。 本篇是Windows系统编译Qt使用的kafka(librdkafka)系列可以不参考的一篇,编译librdkaf…...
RabbitMQ-高级
RabbitMQ-高级 文章目录 RabbitMQ-高级前言:消息可靠性问题1.生产者可靠性1.生产者重连2.生产者确认机制3.生产者代码实现原理 2.MQ的可靠性1.数据持久化2.LazyQueue 3.消费者可靠性1.消费者确认机制1.确认机制2.确认功能 2.失败重试机制1.开启失败重试机制2.多次失…...
深入解析Spring Boot与Kafka集成:构建高效消息驱动微服务
深入解析Spring Boot与Kafka集成:构建高效消息驱动微服务 引言 在现代微服务架构中,消息队列扮演着至关重要的角色,而Apache Kafka凭借其高吞吐量、低延迟和可扩展性,成为了许多企业的首选。本文将详细介绍如何在Spring Boot应用…...
Unreal Engine: Windows 下打包 AirSim项目 为 Linux 平台项目
环境: Windows: win10, UE4.27, Visual Studio 2022 Community.Linux: 22.04 windows环境安装教程: 链接遇到的问题(问题:解决方案) 点击Linux打包按钮,跳转至网页而不是执行打包流程:用VS打开项…...
【图像大模型】FLUX.1-dev:深度解析与实战指南
FLUX.1-dev:深度解析与实战指南 一、引言二、模型架构与技术原理(一)模型架构(二)Rectified Flow 技术(三)指导蒸馏(Guidance Distillation) 三、项目运行方式与执行步骤…...
mariadb 升级 (通过yum)
* 注意下 服务名, 有的服务器上是mysql,有的叫mariadb,mysqld的 #停止 systemctl stop mysql #修改源 vi /etc/yum.repos.d/MariaDB.repo baseurl http://yum.mariadb.org/11.4/centos7-amd64 #卸载 yum remove mysql #安装 yum install MariaDB-server galera-4 MariaDB-…...
Flink 非确定有限自动机NFA
Flink 是一个用于状态化计算的分布式流处理框架,而非确定有限自动机(NFA, Non-deterministic Finite Automaton)是一种在计算机科学中广泛使用的抽象计算模型,常用于正则表达式匹配、模式识别等领域。 Apache Flink 提供了对 NFA…...
Profinet转Ethernet IP主站网关:点燃氢醌生产线的智慧之光!
案例分享:转角指示器和Profinet转EthernetIP网关的应用 在现代工业自动化中,设备和系统之间的高效通信至关重要。最近,我们在某大型化工企业的生产线上实施了一个项目,旨在通过先进的设备和通信技术提高生产效率和安全性。该项目…...
动态IP技术在跨境电商中的创新应用与战略价值解析
在全球化4.0时代,跨境电商正经历从"流量红利"向"技术红利"的深度转型。动态IP技术作为网络基础设施的关键组件,正在重塑跨境贸易的运营逻辑。本文将从技术架构、应用场景、创新实践三个维度,揭示动态IP如何成为跨境电商突…...
WEB安全--SQL注入--Oracle注入
一、Oracle知识点了解 1.1、系统变量与表 版本号:SELECT * FROM V$VERSION 用户名:USER、SYS_CONTEXT(USERENV,SESSION_USER) 库名:ALL_USERS、USER_USERS、DBA_USERS 表名:ALL_TABLES、DBA_TABLES、USER_TABLES 字段名&…...
Unity预制体变体(Prefab Variants)、接口(Interface)、抽象类(Abstract Class)、枚举(Enumeration)
一、预制体变体(Prefab Variants) 预制体变体是什么? 预制体变体是指从同一个基础预制体派生出来的不同版本的预制体。这些变体可以包含不同的组件配置、属性值、子对象或者行为,但它们共享一些共同的基础结构和特性。通过创建预…...
pymol包安装和使用
PyMOL 是一款分子可视化软件,而pymol则是其对应的 Python 包,借助它能够实现对 PyMOL 的编程控制。 主要功能 分子结构可视化:支持展示蛋白质、核酸、小分子等多种分子的 3D 结构。自定义渲染:可对分子的表示方式、颜色以及光照…...
【学习笔记】机器学习(Machine Learning) | 第七章|神经网络(2)
机器学习(Machine Learning) 简要声明 基于吴恩达教授(Andrew Ng)课程视频 BiliBili课程资源 文章目录 机器学习(Machine Learning)简要声明 神经网络在图像识别及手写数字识别中的应用一、神经网络在图像识别中的应用࿰…...
【神经网络与深度学习】model.eval() 模式
引言 在深度学习模型的训练和推理过程中,不同的模式设置对模型的行为和性能有着重要影响。model.eval() 是 PyTorch 等深度学习框架中的关键操作,它用于将模型切换到评估模式(evaluation mode),确保模型在测试和推理阶…...
ASIC和FPGA,到底应该选择哪个?
ASIC和FPGA各有优缺点。 ASIC针对特定需求,具有高性能、低功耗和低成本(在大规模量产时);但设计周期长、成本高、风险大。FPGA则适合快速原型验证和中小批量应用,开发周期短,灵活性高,适合初创企…...
JavaScript 性能优化实战指南
JavaScript 性能优化实战指南 前言 随着前端应用复杂度提升,JavaScript 性能瓶颈日益突出。高效的性能优化不仅能提升用户体验,还能增强系统稳定性和可维护性。本文系统梳理了 JavaScript 性能优化的核心思路、常见场景和实战案例,结合代码…...
Unity3D HUD UI性能优化方案
前言 在Unity3D中实现高性能的HUD UI需要综合考虑渲染效率、CPU开销和内存管理。以下是分步的优化方案: 对惹,这里有一个游戏开发交流小组,大家可以点击进来一起交流一下开发经验呀! 1. 降低Draw Call:合批与图集 …...
晶圆Map图芯片选择显示示例
效果 列表中有四个Mark点,需求是选择某一个点时在Map图中区别显示出来。 实现思路: 根据DataGrid 的行选择 SelectionChanged事件,先循环所有Mark点清除Rectangle的边框大小,再获取选择的芯片,设置Rectangle的边框大小和颜色。 示例代码 1.UI代码 <DataGrid Grid.…...
HarmonyOS实战:自定义时间选择器
前言 最近在日常鸿蒙开发过程中,经常会使用一些时间选择器,鸿蒙官方提供的时间选择器满足不了需求,所以自己动手自定义一些经常会使用到的时间选择器,希望能帮到你,建议点赞收藏! 实现效果 需求分析 默认…...
汽车零部件的EMI抗扰性测试
写在前面 本系列文章主要讲解汽车零部件的EMI抗扰性测试的相关知识,希望能帮助更多的同学认识和了解汽车零部件的EMI抗扰性测试。 若有相关问题,欢迎评论沟通,共同进步。(*^▽^*) 1. 背景介绍 多年以来,电磁干扰(EMI)效应一直是现代电子控制系统中备受关注的一个问题。…...
新能源汽车充电桩管理平台如何利用智慧技术优化资源配置问题?
在“双碳”目标的推动下,我国新能源汽车市场迅猛发展,但充电基础设施的供需失衡问题日益突出。部分区域充电桩利用率低下,而核心城区、高速服务区等场景却面临“一桩难求”的困境。智慧技术的引入为解决这一难题提供了新思路。通过物联网&…...
【zookeeper】--部署3.6.3
文章目录 下载解压创建data和logs配置文件1)创建目录并且编辑 zoo.cfg2)接下来将 node01 的 ZooKeeper 所有文件拷贝至 node02 和 node03。推荐从 node02 和 node03 拷贝4)最后 vim /etc/profile 配置环境变量,环境搭建结束。配完环境变量后 source /etc…...
[低代码] 明道云调用本地部署 Dify 的进阶方法
在低代码开发平台明道云中,集成外部智能服务(如 Dify)可以极大地提升自动化和智能化能力。之前我们介绍了使用“发送自定义 API”节点直接调用本地部署的 Dify 服务的方法,虽然简单直观,但该方式存在一些限制,比如无法设置 Timeout、逻辑复用性差等问题。 为了构建更稳定…...
ICU库交叉编译
交叉编译步骤 Step 1: 先进行本机编译 ./runConfigureICU Linux/gccmake Step 2: 执行交叉编译 source /opt/fsl-imx-fb/4.14-sumo/environment-setup-cortexa9hf-neon-poky-linux-gnueabimkdir cross_install./configure --disable-samples --disable-tests --prefix/medi…...
永磁同步电机高性能控制算法(22)——基于神经网络的转矩脉动抑制算法为什么低速时的转速波动大?
0. 前言 在之前的知乎上发过一些转矩脉动抑制/谐波电流抑制的算法。例如: https://zhuanlan.zhihu.com/p/24723996895https://zhuanlan.zhihu.com/p/24723996895 这些算法基本上都需要先知道谐波的频率。 重复控制这个算法虽然可以抑制掉某个频率及其所有整数倍的…...
Java大厂面试实战:Spring Boot与微服务场景中的技术点解析
Java大厂面试实战:Spring Boot与微服务场景中的技术点解析 第一轮:基础技术了解 面试官:谢飞机,你好。从简历上看,你熟悉Spring Boot,那我们来聊聊它的核心功能吧。Spring Boot有哪些主要的特性ÿ…...
Pycharm 选择Python Interpreter
你的系统可能有多个 Python 环境,比如: macOS 自带的 /usr/bin/python3 你用 brew install python 安装的 /opt/homebrew/bin/python3 你可能还用了虚拟环境(venv 或 conda) PyCharm 默认配置可能用的是一个虚拟环境ÿ…...
文件夹如何打包成jar包
应用场景 主要是:比如 maven 引入一个依赖(其实就是下载了一个 jar 包),然后需要修改 jar 包里面的某个文件,然后再重新打包成 jar 包,如下图: 使用方法 使用压缩工具打开这个 jar 包…...
sqli-labs第九关—‘时间盲注
一:判断闭合类型 先按照之前的判断方式判断,发现无论输入什么都显示You are in.......... 可以考虑使用时间盲注: 二:时间盲注Time-based Blind: 1.解释: 通过时间延迟判断结果 2.核心原理:…...
10.15 LangChain v0.3重磅升级:Tool Calling技术颠覆大模型工具调用,效率飙升300%!
LangChain v0.3 技术生态与未来发展:支持 Tool Calling 的大模型 关键词:LangChain Tool Calling, 大模型工具调用, @tool 装饰器, ToolMessage 管理, Few-shot Prompting 1. Tool Calling 的技术革新 LangChain v0.3 的工具调用(Tool Calling)功能标志着大模型应用开发进…...
【C++】哈希的概念与实现
1.哈希概念 通过某种函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,可以不经过任何比较,一次直接从表中得到要搜索的元素。 当向该结构中: 插入元素: 根据待插入元素的关键码,以此函数计算出该元素的…...
Spring 代理与 Redis 分布式锁冲突:一次锁释放异常的分析与解决
Spring 代理与 Redis 分布式锁冲突:一次锁释放异常的分析与解决 Spring 代理与 Redis 分布式锁冲突:一次锁释放异常的分析与解决1. 问题现象与初步分析2 . 原因探究:代理机制对分布式锁生命周期的干扰3. 问题复现伪代码4. 解决方案࿱…...
vue Element-ui对图片上传和选用时的比例控制
vue Element-ui对图片上传和选用时的比例控制 在后台上传图片和选用已经上传的图片时,往往会因为图片的比例控制不到位导致在客户端渲染时效果差强人意,虽然可以在操作时选择合适的比例上传,但必要的控制还是能完成渲染时良好的体验…...
UE5在C++项目中判断不同平台
在Unreal Engine 5的C代码中,可以通过以下方法判断当前运行的平台(如Android、Windows、iOS),并根据平台执行不同的逻辑: 方法1:使用预处理器宏(编译时判断) Unreal Engine提供了一…...
用 CodeBuddy 实现「IdeaSpark 每日灵感卡」:一场 UI 与灵感的极简之旅
项目起点:一次随手的灵感 有时候,灵感稍纵即逝,尤其是面对屏幕发呆的时候。那天我忽然想到——要是能有一个每天弹出一句创意提示、灵感金句的应用就好了,最好配上简洁但有氛围感的 UI,像抽一张卡片一样,轻…...
std::ranges::views::as_const 和 std::ranges::as_const_view
std::ranges::views::as_const 和 std::ranges::as_const_view 是 C23 引入的视图适配器,用于生成一个不可变的视图,确保通过该视图访问元素时,元素被视为常量。以下是详细说明和示例: 基本概念 功能: 将输入范围的元素…...
3D 数据交换格式(.3DXML)简介
3DXML 是一种基于 XML 的 3D 数据交换格式,由达索系统(Dassault Systmes)开发,主要用于其 CATIA、SOLIDWORKS 和 3DEXPERIENCE 等产品中。 基本概述 全称:3D XML开发者:达索系统主要用途:3D…...
深度解析3D模型生成器:基于StyleGAN3与PyTorch3D的多风格生成工具开发实战
引言:跨模态生成的革命性突破 在元宇宙与数字孪生技术蓬勃发展的今天,3D内容生成已成为制约产业发展的关键瓶颈。传统建模方式依赖专业软件和人工操作,而基于深度学习的生成模型正颠覆这一范式。本文将深入解析如何构建支持多风格生成的3D模…...
DTAS 3D多约束装配助力悬架公差分析尺寸链计算:麦弗逊/双叉臂/多连杆/H臂一网打尽
摘要:汽车四轮定位参数与悬架密切相关。汽车悬架对于车辆的行驶性能、安全性和舒适性至关重要。DTAS 3D提供了各类型悬架的公差仿真分析方法。 关键字:DTAS 3D、前后悬架、公差仿真分析、 运动耦合 一、悬架公差分析综述 悬架是车身(或车架…...
CRMEB多商户预约服务上门师傅端
随着科技的不断发展,人们对于生活品质的要求也在不断提高。在这个过程中,各种便捷的上门服务应运而生,为我们的生活带来了极大的便利。而CRMEB多商户预约服务上门师傅端正是这样一款致力于为用户提供专业、高效、便捷的上门服务的应用。 一、…...
labview硬件开发板——LED流水灯
函数 : int DoSetV12( unsigned char chan, unsigned char state); 功能 :设置 OUT0—3 的输出状态,输入参数为 8 位字符型, Chan:4 位要设置的通道,0 对应 OUT1……3 对应 OUT4 ( 注意:开…...
linux——mysql故障排查与生产环境优化
目录 一,mysql数据库常见的故障 1,故障现象1 2,故障现象2 3,故障现象3 4,故障现象4 5,故障现象5 6,故障现象6 二&…...
MongoDB及spring集成
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统 用文档存数据,每个文档可以看作是一个键值对集合,类似于 JSON 对象 MongoDB 支持索引以提高查询性能,并且可以在任何属性上创建索引 文档(Document) M…...
一发入魂:极简解决 SwiftUI 复杂视图未能正确刷新的问题(下)
概述 各位似秃非秃小码农们都知道,在 SwiftUI 中视图是状态的函数,这意味着状态的改变会导致界面被刷新。 但是,对于有些复杂布局的 SwiftUI 视图来说,它们的界面并不能直接映射到对应的状态上去。这就会造成一个问题:状态的改变并没有及时的引起 UI 的变化。 如上图所示…...
关于我在使用stream().toList()遇到的问题
关于我在使用stream().toList()遇到的问题 问题描述 在测试以上程序的时候抛出了空指针异常 于是我以为是我数据库中存在null字段,但查看后发现并不存在为null的数据 问题排查 起初我以为问题出现在sort排序方法这,事实也确实是,当我把s…...
如何通过生成式人工智能认证(GAI认证)提升自己的技能水平?
当生成式人工智能从实验室走向生产线,职场人正面临一个关键抉择:是被动等待技术浪潮的冲刷,还是主动构建适应未来的能力护城河?职业技能培训的终极目标,早已超越“掌握工具”的初级阶段,转向“构建技术认知体系”的深层需求。生成式人工智能认证(GAI认证)的兴起,正是这…...
通讯协议串口 | 485标准
485通讯(RS-485)详解 一、基本概念与核心原理 定义与标准 RS-485(又称EIA-485)是一种由美国电子工业协会(EIA)制定的差分信号串行通信标准,属于OSI模型的物理层协议。它专为工业环境设计&#…...
新能源充电桩智慧管理系统:未来新能源汽车移动充电服务发展前景怎样?
随着全球新能源汽车保有量的持续攀升,传统固定充电桩建设速度已难以满足用户日益增长的补能需求。在这一背景下,移动充电服务作为充电基础设施的重要补充,正展现出巨大的发展潜力。政策支持、技术进步(如快充、智能调度࿰…...