SpringBoot使用注解实现参数校验

文章目录

  • 参数校验
    • - Validation
    • - Hibernate Validator
  • 校验注解
    • 注解通用属性
    • - Validator 内置注解
    • - Hibernate Validator 附加注解
  • 校验开启
    • @Valid和@Validated
  • 校验分类
    • - Controller校验
    • - Spring Bean校验
  • 校验使用
    • - Controller:参数对象校验
    • - Spring Bean:方法返回值对象校验
    • - Spring Bean:方法参数对象校验
    • 分组校验
      • - Controller:方法参数分组校验
    • 嵌套校验
      • - Controller:方法参数嵌套校验
      • - Spring Bean:方法返回值嵌套校验
      • - Spring Bean:方法参数嵌套校验
  • 自定义注解


参数校验

Spring Boot框架默认使用Hibernate Validator作为校验器实现。参数校验使用JSR-303规范定义的校验注解来实现的。

实际上,在Spring项目中,参数校验并仅支持用在Controller层上面,其实是支持用在所有的Spring Bean上(Controller、Service、Repository等)。

配置依赖:

  1. SpringMVC项目:

    <dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.18.Final</version>
    </dependency>
    
  2. SpringBoot项目:

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

- Validation

javax.validation 并不是 JDK 的一部分,它是 Java EE 的一部分,它提供了基于注释和 API 的对象校验功能,即 JSR 303 规范。JSR 303 规范定义了一套用于在 JavaBean 中定义验证约束的元数据模型并提供用于编程方式和声明式验证的 API。

  • 在 JavaEE6 中,这个规范被定义为 JSR 303
  • 在 JavaEE7 中则成为了 JSR 349
  • 在 JavaEE8 中成为 JSR 380

javax.validation 包中包含了很多注解,如@NotNull、@Size、@Pattern,它们可以用来对 JavaBean 中的属性进行各种验证,以保证数据的有效性和安全性。

需要注意的是,虽然 JSR-303 规范是 Java EE 的一部分,但我们仍然可以在非 Java EE 的应用程序中使用它,例如 Spring Boot、Spring MVC 等。在使用时需要导入 javax.validation 的 jar 包或者其他支持JSR 303规范的第三方库。

- Hibernate Validator

hibernate-validator是一个流行的Java数据校验器库,它基于JSR 303规范实现了Bean Validation 2.0 API,并提供了许多常用的校验注解和校验器。

校验注解

注解通用属性

  • message:错误提示信息

    可以使用 {} 占位符来引用注解中的属性值或自定义的文本。可以在错误消息中动态地插入变量的值,使错误消息更具体和有意义。

    使用方式:

    • 自定义文本
      @Size(min = 5, max = 10, message = "用户名长度不正确")
      private String username;
      
    • 引用注解中的属性值
      @Size(min = 5, max = 10, message = "用户名长度必须介于 {min} 到 {max} 之间")
      private String username;
      
    • 引用配置文件配置参数的值
      @Size(min = 5, max = 10, message = "{javax.validation.constraints.Size.message}")
      private String username;
      
      为了提供国际化和本地化支持,错误消息通常会使用特定的键(key)来标识。这些键将在校验过程中与消息资源包(message bundle)中的实际错误消息文本进行映射。
  • groups:所属的校验组

    校验组是一种逻辑分组,可以根据不同的场景或需求对校验规则进行分组。默认情况下,参数校验不属于任何校验组,即属于默认组(Default)。

  • payload:携带额外的信息负载

    这些信息负载可以在校验失败时获得。通常情况下,我们不需要使用该属性。

- Validator 内置注解

注解注解的其它属性注解描述
@Null验证对象是否为 null
@NotNull验证对象不为 null
@NotBlank验证字符串不为空,去除前后空格后长度大于 0
@NotEmpty验证对象不为 null 且不为空(如字符串、集合、数组等),去除前后空格后长度大于 0
@Sizemin:最小值
max:最大值
验证对象(字符串、集合、数组等)长度在 min 和 max 之间
@Maxvalue:最大值验证数值(byte、short、int、long 等)是否小于等于指定的最大值
@Minvalue:最小值验证数值(byte、short、int、long 等)是否大于等于指定的最小值
@DecimalMaxvalue:最大值
inclusive:是否包含边界
验证 BigDecimal 和 BigInteger 的值是否小于等于指定的最大值
@DecimalMinvalue:最小值
inclusive:是否包含边界
验证 BigDecimal 和 BigInteger 的值是否大于等于指定的最小值
@Digitsinteger:整数位数
fraction:小数位数
验证数值是否符合整数位数和小数位数要求
@Patternregexp:正则表达式验证字符串是否符合指定的正则表达式
@Email验证字符串是否符合 Email 格式
@Future验证日期是否为将来某个时间
@FutureOrPresent验证日期是否为将来某个时间或当前时间
@Past验证日期是否为过去某个时间
@PastOrPresent验证日期是否为过去某个时间或当前时间
@AssertTrue验证 boolean 类型是否为 true
@AssertFalse验证 boolean 类型是否为 false
@Positive验证数值是否为正数
@PositiveOrZero验证数值是否为正数或零
@Negative验证数值是否为负数
@NegativeOrZero验证数值是否为负数或零

@Max(value)、@Min(value)、@DecimalMax(value)、@DecimalMin(Value)区别:

  • @Max、@Min接受一个Long类型的值
  • @DecimalMax、@DecimalMin接受一个字符串类型的值(BigDecimal的字符串表示形式,因此可以是小数)
  • 数字超过Long.MAX_VALUE或Long.MIN_VALUE以下或者数字是小数,@DecimalMax、@DecimalMin是唯一的选择。

- Hibernate Validator 附加注解

注解注解的其它属性注解描述
@Lengthmin:最小长度
max:最大长度
验证字符串的长度是否在指定范围内
@Rangemin:最小值
max:最大值
验证数字(BigDecimal, BigInteger, String, byte, short, int, long和原始类型的包装类 )是否在指定范围内
@UniqueElements验证集合中的元素是否唯一
@URLprotocol:协议
host:主机
port:端口
regexp:正则表达式
flags:标志
验证字符串是否符合 URL 格式要求
@Hexadecimal验证字符串是否是十六进制的格式
@ISBNtype:ISBN类型验证字符串是否是有效的ISBN码
@CreditCardNumberignoreNonDigitCharacters:是否忽略非数字字符验证字符串是否是有效的信用卡号码
@Currencyvalue:货币代码验证字符串是否是有效的货币代码
@CodePointLengthmin:最小码点长度
max:最大码点长度
验证字符串的码点长度是否在指定范围内
@Mod10Check验证字符串是否通过Mod 10算法校验
@Mod11Check验证字符串是否通过Mod 11算法校验
@LuhnCheck验证字符串是否通过Luhn算法校验
@EANtype:EAN 类型验证字符串是否是有效的 EAN(欧洲文章编号)码
@ScriptAssertlang:脚本语言
script:脚本内容
alias:脚本别名
reportOn:指定将错误报告应用于哪些属性
验证对象的属性是否满足指定的脚本表达式
@ParameterScriptAssertlang:脚本语言
script:脚本内容
验证对象的属性是否满足指定的脚本表达式,可以在脚本中引用方法参数

校验开启

@Valid和@Validated是用于Spring框架中数据校验的注解。

@Valid和@Validated

对比@Valid@Validated
校验规则JavaEE JSR-303(Bean Validation)规范定义的Spring定义的,对@Valid进行了二次封装。
所以既支持使用JSR-303规范的注解,也可以使用Spring提供的额外校验规则
使用范围用在方法、参数、字段上用在类、参数上
分组校验不支持支持
嵌套校验支持
需要在嵌套的字段上面也加上@Valid
不支持
异常处理校验失败时抛出异常MethodArgumentNotValidException校验失败时抛出异常ConstraintViolationException

校验分类

Spring支持校验范围可分为以下两类:

  • Controller校验
  • Spring Bean校验(包括Controller)

- Controller校验

Spring对Controller层的参数校验进行了专门处理,当请求到达Controller层前会先找到匹配的方法参数解析器(HandlerMethodArgumentResolver)进行参数解析,参数解析的过程中包含参数校验。

HandlerMethodArgumentResolver分析可参考:https://blog.csdn.net/JokerLJG/article/details/134754757

源码分析:

HandlerMethodArgumentResolver接口:

public interface HandlerMethodArgumentResolver {// 判断该解析器是否支持解析给定的方法参数boolean supportsParameter(MethodParameter parameter);// 解析给定的方法参数,并返回解析后的参数值Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}

下面以HandlerMethodArgumentResolver的其中一个实现类来分析。
RequestResponseBodyMethodProcessor类:

	@Overridepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {parameter = parameter.nestedIfOptional();Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType());String name = Conventions.getVariableNameForParameter(parameter);if (binderFactory != null) {WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);if (arg != null) {validateIfApplicable(binder, parameter);if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());}}if (mavContainer != null) {mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());}}return adaptArgumentIfNecessary(arg, parameter);}protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {// 遍历方法参数上的注解Annotation[] annotations = parameter.getParameterAnnotations();for (Annotation ann : annotations) {// 如果注解是Validated或注解以Valid开头时,进行参数校验Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});binder.validate(validationHints);break;}}}
  • 获取方法参数上的所有注解,遍历注解
  • 当注解是Validated或注解以Valid开头时,进行参数校验

- Spring Bean校验

Spring Bean校验底层是通过AOP的方式实现的,通过MethodValidationPostProcessor动态注册AOP切面(以Validated注解为切点),然后使用MethodValidationInterceptor对切点方法织入增强。

注意:Spring Bean校验对Controller及其他Spring Bean都适用。

MethodValidationPostProcessor类:

	public void afterPropertiesSet() {// 为所有`@Validated`标注的Bean创建切面Pointcut pointcut = new AnnotationMatchingPointcut(this.validatedAnnotationType, true);// 创建Advisor进行增强this.advisor = new DefaultPointcutAdvisor(pointcut, createMethodValidationAdvice(this.validator));}// 创建Advice,本质就是一个方法拦截器(拦截Bean的所有方法)protected Advice createMethodValidationAdvice(@Nullable Validator validator) {return (validator != null ? new MethodValidationInterceptor(validator) : new MethodValidationInterceptor());}

MethodValidationInterceptor类:

	@Override@SuppressWarnings("unchecked")public Object invoke(MethodInvocation invocation) throws Throwable {// 无需增强的方法,直接跳过if (isFactoryBeanMetadataMethod(invocation.getMethod())) {return invocation.proceed();}// 获取校验分组信息Class<?>[] groups = determineValidationGroups(invocation);ExecutableValidator execVal = this.validator.forExecutables();Method methodToValidate = invocation.getMethod();Set<ConstraintViolation<Object>> result;// 方法参数校验try {result = execVal.validateParameters(invocation.getThis(), methodToValidate, invocation.getArguments(), groups);} catch (IllegalArgumentException ex) {methodToValidate = BridgeMethodResolver.findBridgedMethod(ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass()));result = execVal.validateParameters(invocation.getThis(), methodToValidate, invocation.getArguments(), groups);}if (!result.isEmpty()) {throw new ConstraintViolationException(result);}Object returnValue = invocation.proceed();// 方法返回值校验result = execVal.validateReturnValue(invocation.getThis(), methodToValidate, returnValue, groups);if (!result.isEmpty()) {throw new ConstraintViolationException(result);}return returnValue;}
  • 方法参数校验:当方法参数上有@Valid或参数校验注解(@NotNull、@NotBlank、@Length等)时,会进行校验。
  • 方法返回值校验:当方法参数上有@Valid或参数校验注解(@NotNull、@NotBlank、@Length等)时,会进行校验。

校验使用

校验分类校验范围
Controller方法参数对象校验Controller适用
Spring Bean方法返回值对象校验Controller及其他Spring Bean都适用
Spring Bean方法参数对象校验Controller及其他Spring Bean都适用

注意:下面的示例中,项目做了全局异常处理。

- Controller:参数对象校验

对Controller方法参数对象进行校验。

@Data
public class User {@NotNull(message = "userId不能为空")public String userId;
}
  • 使用@Valid+校验注解:

    方法参数上加@Valid,参数对象中使用校验注解

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@PostMapping("test11")public User test11(@RequestBody @Valid User user) {return user;}
    }
    

    请求

    curl 'http://127.0.0.1:8888/valid/test11' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "userId不能为空","data": null
    }
    
  • 使用@Validated+校验注解:

    方法参数上加@Validated,参数对象中使用校验注解

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@PostMapping("test12")public User test12(@RequestBody @Validated User user) {return user;}
    }
    

    请求

    curl 'http://127.0.0.1:8888/valid/test12' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "userId不能为空","data": null
    }
    

- Spring Bean:方法返回值对象校验

对Spring Bean(包括Controller)方法返回值对象进行校验。

注意:方法返回值对象校验时,注解放到方法前面或整个方法上面都是相同的效果。

@Data
public class User {@NotNull(message = "userId不能为空")public String userId;
}
  • 使用@Validated+@Valid+校验注解

    Spring Bean类上加@Validated,方法返回值上加@Valid,返回值对象中使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@Autowiredprivate ValidService validService;@PostMapping("test13")public User test13(@RequestBody User user) {return validService.test13(user);}
    }@Validated
    @Service
    public class ValidService {public @Valid User test13(User user) {return user;}
    }

    请求

    curl 'http://127.0.0.1:8888/valid/test13' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "userId不能为空","data": null
    }
    
  • 使用@Validated+校验注解

    Spring Bean类上加@Validated,方法返回值上直接使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@Autowiredprivate ValidService validService;@PostMapping("test14")public @NotNull User test14(@RequestBody User user) {return validService.test14(user);}
    }@Validated
    @Service
    public class ValidService {public @NotNull User test14(User user) {return null;}
    }
    

    请求

    curl 'http://127.0.0.1:8888/valid/test14' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "不能为null","data": null
    }
    

- Spring Bean:方法参数对象校验

对Spring Bean(包括Controller)方法参数对象进行校验。

@Data
public class User {@NotNull(message = "userId不能为空")public String userId;
}
  • 使用@Validated+@Valid+校验注解

    Spring Bean类上加@Validated,方法参数上加@Valid,参数对象中使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@Autowiredprivate ValidService validService;@PostMapping("test15")public User test15(@RequestBody User user) {return validService.test15(user);}
    }@Validated
    @Service
    public class ValidService {public User test15(@Valid User user) {return user;}
    }
    

    请求

    curl 'http://127.0.0.1:8888/valid/test15' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "userId不能为空","data": null
    }
    
  • 使用@Validated+校验注解

    Spring Bean类上加@Validated,方法参数上直接中使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@Autowiredprivate ValidService validService;@PostMapping("test16")public User test16(@RequestBody User user) {return validService.test16(null);}
    }@Validated
    @Service
    public class ValidService {public User test16(@NotNull User user) {return user;}
    }

    请求

    curl 'http://127.0.0.1:8888/valid/test16' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "不能为null","data": null
    }
    

分组校验

@Data
public class User {@NotNull(message = "userId不能为空")public String userId;@NotNull(message = "userName不能为空", groups = {AddGroup.class})public String userName;@NotNull(message = "age不能为空", groups = {UpdateGroup.class})public String age;
}

- Controller:方法参数分组校验

对Controller方法参数对象进行分组校验。

  • 使用@Validated+@Valid+校验注解

    方法参数上加@Validated,并指定分组value属性,参数对象中的字段加校验注解并指定分组groups属性。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@PostMapping("test17")public User test17(@RequestBody @Validated({AddGroup.class}) User user) {return user;}@PostMapping("test18")public User test18(@RequestBody @Validated({UpdateGroup.class}) User user) {return user;}
    }
    

    请求

    curl 'http://127.0.0.1:8888/valid/test17' -H 'Content-Type: application/json' -d '{}'curl 'http://127.0.0.1:8888/valid/test18' -H 'Content-Type: application/json' -d '{}'
    

    结果

    {"code": 501,"msg": "userName不能为空","data": null
    }{"code": 501,"msg": "age不能为空","data": null
    }
    

嵌套校验

@Data
public class User {@NotNull(message = "userId不能为空")public String userId;@Validpublic Sex sex;
}@Data
public class Sex {@NotNull(message = "sexName不能为空")public String sexName;
}

- Controller:方法参数嵌套校验

对Controller方法参数对象进行嵌套校验。

  • 使用@Validated+@Valid+校验注解

    方法参数上加@Validated,参数对象中的字段加@Valid,字段对象内再使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@PostMapping("test19")public User test19(@RequestBody @Validated User user) {return user;}
    }

    请求

    curl 'http://127.0.0.1:8888/valid/test19' -H 'Content-Type: application/json' -d '{"userId": "userId_a7699554a547","sex": {}
    }'
    

    结果

    {"code": 501,"msg": "sexName不能为空","data": null
    }
    
  • 使用@Valid+@Valid+校验注解

    方法参数上加@Valid,参数对象中的字段加@Valid,字段对象内再使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@PostMapping("test20")public User test20(@RequestBody @Valid User user) {return user;}
    }
    

    请求

    curl 'http://127.0.0.1:8888/valid/test20' -H 'Content-Type: application/json' -d '{"userId": "userId_a7699554a547","sex": {}
    }'
    

    结果

    {"code": 501,"msg": "sexName不能为空","data": null
    }
    

- Spring Bean:方法返回值嵌套校验

对Spring Bean(包括Controller)方法返回值对象进行嵌套校验。

  • 使用@Validated+@Valid+@Valid+校验注解

    Spring Bean类上加@Validated,方法返回值上加@Valid,返回值对象中字段加@Valid,字段内使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@Autowiredprivate ValidService validService;@PostMapping("test21")public User test21(@RequestBody User user) {return validService.test21(user);}
    }@Validated
    @Service
    public class ValidService {public @Valid User test21(User user) {return user;}
    }

    请求

    curl 'http://127.0.0.1:8888/valid/test21' -H 'Content-Type: application/json' -d '{"userId": "userId_a7699554a547","sex": {}
    }'
    

    结果

    {"code": 501,"msg": "sexName不能为空","data": null
    }
    

- Spring Bean:方法参数嵌套校验

对Spring Bean(包括Controller)方法参数对象进行嵌套校验。

  • 使用@Validated+@Valid+@Valid+校验注解

    Spring Bean类上加@Validated,方法参数上加@Valid,参数对象中字段加@Valid,字段内使用校验注解。

    代码

    @RestController
    @RequestMapping("valid")
    public class ValidController {@Autowiredprivate ValidService validService;@PostMapping("test22")public User test22(@RequestBody User user) {return validService.test22(user);}
    }@Validated
    @Service
    public class ValidService {public User test22(@Valid User user) {return user;}
    }
    
    curl 'http://127.0.0.1:8888/valid/test22' -H 'Content-Type: application/json' -d '{"userId": "userId_a7699554a547","sex": {}
    }'
    

    结果

    {"code": 501,"msg": "sexName不能为空","data": null
    }
    

自定义注解

自定义参数校验工具的步骤:

  1. 自定义注解
  2. 自定义Validator

1. 自定义注解

定义一个IPV4地址的校验注解。

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;@Documented
@Target({ METHOD, FIELD, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(Ipv4.List.class)
@Constraint(validatedBy = {Ipv4Validator.class})
public @interface Ipv4 {String message() default "not is Ipv4";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};@Target({ METHOD, FIELD, PARAMETER, TYPE_USE })@Retention(RUNTIME)@Documented@interface List {Ipv4[] value();}
}

2. 自定义Validator

定义一个校验器,用于验证是否为IPV4地址。

import cn.hutool.core.lang.Validator;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class Ipv4Validator implements ConstraintValidator<Ipv4, String> {@Overridepublic void initialize(Ipv4 constraintAnnotation) {ConstraintValidator.super.initialize(constraintAnnotation);}@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {// 对象为空验证通过if (value == null) {return true;}return Validator.isIpv4(value);}
}

使用示例:

代码

@Validated
@RestController
@RequestMapping("valid")
public class ValidController {@GetMapping("test23")public String test23(@Ipv4(message = "ip不是IPV4地址") String ip) {return ip;}
}

请求

curl 'http://127.0.0.1:8888/valid/test23?ip=1.1.1'

结果

{"code": 501,"msg": "ip不是IPV4地址","data": null
}

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

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

相关文章

关系模式化的规范化理论

数据库规范化中的“函数依赖”是理解和应用规范化过程的关键概念。函数依赖描述了一个或多个列&#xff08;属性&#xff09;如何唯一确定另一个列的值。 函数依赖的基本概念&#xff1a; 函数依赖&#xff1a;如果在一个给定的关系中&#xff0c;对于某个属性集合 ( A ) 的每…

巧用RTL原语实现MUX门级映射

对于前端设计人员&#xff0c;经常会需要一个MUX来对工作模式&#xff0c;数据路径进行明确&#xff08;explicit&#xff09;的声明&#xff0c;这个对于中后端工程师下约束也很重要。这里介绍一种巧用的RTL原语&#xff0c;实现MUX的方法。闲言少叙&#xff0c;ICerGo&#x…

如何退回chrome旧版ui界面?关闭Chrome浏览器新 UI 界面

之前启用新UI的方式 Chrome 已经很久没有进行过大的样式修改&#xff0c;但近期在稳定分支中添加了新的 flags 实验性标志&#xff0c;带来了全新的设计与外观&#xff0c;启用方式如下&#xff1a; 在 Chrome 浏览器的搜索栏中输入并访问 chrome://flags 搜索“refresh 2023…

西南科技大学数字电子技术实验六(智力竞赛抢答器的设计及FPGA实现)预习报告

一、计算/设计过程 说明&#xff1a;本实验是验证性实验&#xff0c;计算预测验证结果。是设计性实验一定要从系统指标计算出元件参数过程&#xff0c;越详细越好。用公式输入法完成相关公式内容&#xff0c;不得贴手写图片。&#xff08;注意&#xff1a;从抽象公式直接得出结…

彻底解决公网ip无法访问服务器的问题

用服务器的公网ip访问突然提示页面无法访问了&#xff0c;之前还是ok的&#xff1a; 解决方案&#xff1a; 步骤1. 检查云服务器的安全组规则是否有添加80端口映射&#xff0c;如果没有需要手动添加&#xff0c;否则不能使用公网访问&#xff0c;检查了一下是有的&#xff1…

陵园殡仪馆网站建设的效果如何

陵园墓地的需求度众多周知非常高&#xff0c;无论墓地坑位咨询还是事项/环境展示、资料预览等都是常见事项&#xff0c;由于行业的特殊性&#xff0c;对正常客户来说&#xff0c;并不会知悉各个事项、价格、服务、流程等内容。 而对企业来说&#xff0c;也有获客、品牌扩张等需…

TCP/IP详解——网络基本概念

文章目录 一、网络基本概念1. OSI 7层模型1.1 每层对应的协议1.2 每层涉及的设备1.2.1 物理层设备1.2.2 数据链路层设备1.2.3 网络层设备1.2.4 传输层设备1.2.5 交换机和路由器的应用1.2.6 问题 2. TCP/IP 4层模型3. 物理层传输介质3.1 冲突域 4. 数据链路层4.1 以太网帧结构4.…

Ubuntu设置kubelet启动脚本关闭swap分区

查看swap分区 swapon -s打开swap分区 swapon -a查看/etc/fstab下所有固化的swap分区&#xff0c;注释 vi /etc/fstab修改kubelet.conf文件 vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf添加 ExecStartPre/sbin/swapoff -a生效 systemctl daemon-reload sys…

挑战52天学小猪佩奇笔记--day19

52天学完小猪佩奇--day19 ​【本文说明】 本文内容来源于对B站UP 脑洞部长 的系列视频 挑战52天背完小猪佩奇----day19 的视频内容总结&#xff0c;方便复习。强烈建议大家去关注一波UP&#xff0c;配合UP视频学习。 day19的主题&#xff1a;新鞋子 人物对话&#xff1a; 语境…

GPT-4V 在保险行业的应用

在科技的进步中&#xff0c;人工智能与大数据技术的结合产生了巨大的能量&#xff0c;推动了各行各业的创新与变革。OpenAI&#xff0c;作为全球领先的人工智能研发机构&#xff0c;在今年的9月25日&#xff0c;以一种崭新的方式&#xff0c;升级了其旗下的GPT-4模型。这次的升…

HNU计算机视觉作业一

前言 选修的是蔡mj老师的计算机视觉&#xff0c;上课还是不错的&#xff0c;但是OpenCV可能需要自己学才能完整把作业写出来。由于没有认真学&#xff0c;这门课最后混了80多分&#xff0c;所以下面作业解题过程均为自己写的&#xff0c;并不是标准答案&#xff0c;仅供参考 …

LeetCode力扣每日一题(Java):58、最后一个单词的长度

一、题目 二、解题思路 1、我的思路 先将字符串转换成字符数组 由于我们需要获取最后一个单词的长度&#xff0c;所以我们从后往前遍历字符数组 我们还需判断所遍历的字符是不是字母&#xff0c;即判断每个字符对应的ASCII值即可&#xff0c;用计数器count来储存单词长度 …

【RHEL9】Fatal glibc error: CPU does not support x86-64-v2

问题描述 RHEL 9要求x86_64的CPU支持x86-64-v2&#xff0c;x86-64-v2需要处理器支持 CMPXCHG16B、LAHF-SAHF、POPCNT、SSE3、SSE4.1、SSE4.2、SSSE3 等现代指令集 检查CPU是否支持x86-64-v2的方法 #!/bin/sh flags$(cat /proc/cpuinfo | grep flags | head -n 1 | cut -d: -…

1分钟让你快速了解私域运营流量增长底层逻辑!

私域运营说的直白一点&#xff0c;其实就是将用户引入到私域矩阵中&#xff0c;持续性的付费转化&#xff0c;维护好老顾客的同时&#xff0c;并通过他们分享裂变&#xff0c;低成本吸引新客户&#xff0c;再用不同的营销玩法&#xff0c;将新客户转化为老客户的一系列过程。

使用HTTP协议在Linux上进行API调用

在Linux系统上使用HTTP协议进行API调用是一种常见的操作&#xff0c;有时候我们需要调用一些外部API来获取数据或者进行自动化操作。下面是一个使用HTTP协议在Linux上进行API调用的代码示例&#xff0c;希望能够帮助你更好地理解这个过程。 首先&#xff0c;我们需要使用curl命…

【同步FIFO_2023.12.13】

同步fifo&#xff0c;写时钟和读时钟为同一个时钟&#xff0c;用于交互数据缓冲 fifo的深度&#xff1a;同一块数据内存的大小 reg [2:0] Mem [8];//宽度3&#xff0c;深度8典型同步fifo的三部分 fifo写控制逻辑&#xff1a;写地址、写有效信号&#xff0c;fifo写满、写错等状…

金数据企业版:广告推广效率提升的关键,无代码API集成与连接技术

深入理解无代码开发与API集成的重要性 在当今的电商竞争环境下&#xff0c;企业必须寻找提高效率和灵活性的办法。无代码开发平台&#xff0c;如金数据&#xff0c;提供了一种创新的方式来应对快速变化的市场需求&#xff0c;特别是在API集成方面。无代码开发意味着企业可以通…

减持股份对股票的影响,好还是不好?

减持股份对股票是好还是不好&#xff1f;这是一个很多投资者都关心的问题&#xff0c;因为减持股份会影响股票的价格、流动性和信心。减持股份的原因和影响是多方面的&#xff0c;没有一个简单的答案&#xff0c;需要根据具体的情况进行分析。下面&#xff0c;我将从几个方面来…

MT1527 回文串

利用指针判断字符串是否为回文。(正读和反读都一样的字符串) 输入格式&#xff1a; 输入字符串 输出格式&#xff1a; 输出YES或者NO 输入&#xff1a; wenew 输出&#xff1a; YES #include <iostream> #include <algorithm> #include <string> using …

云渲染怎么提升效果图的画质?云渲染对效果图未来影响

在当今高速发展的视觉设计行业中&#xff0c;高质量的效果图不仅是展示设计成果的重要手段&#xff0c;也是设计沟通和营销的关键。无论是建筑设计、室内设计还是工业样品的视觉化&#xff0c;效果图的精细程度与渲染速度对项目的成功至关重要。对于许多追求卓越和效率的设计师…