当前位置: 首页 > news >正文

【谷粒商城之JSR303数据校验和集中异常处理】

本笔记内容为尚硅谷谷粒商城JSR303数据校验和集中异常处理部分

目录

一、简介

二、SR303数据校验使用步骤

1、引入依赖

2、给参数对象添加校验注解

常见的注解

3、接口参数前增加@Valid 开启校验

三、异常的统一处理

四、分组解决校验

1、创建Groups 

2、添加分组 

五、自定义校验注解

1、创建约束规则

2、创建约束校验器

3、自定义校验注解校验失败后的返回信息


一、简介


JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation。

在任何时候,当你要处理一个应用程序的业务逻辑,数据校验是你必须要考虑和面对的事情。应用程序必须通过某种手段来确保输入进来的数据从语义上来讲是正确的。在通常的情况下,应用程序是分层的,不同的层由不同的开发人员来完成。很多时候同样的数据验证逻辑会出现在不同的层,这样就会导致代码冗余和一些管理的问题,比如说语义的一致性等。为了避免这样的情况发生,最好是将验证逻辑与相应的域模型进行绑定。

Bean Validation 为 JavaBean 验证定义了相应的元数据模型和 API。缺省的元数据是 Java Annotations,通过使用 XML 可以对原有的元数据信息进行覆盖和扩展。在应用程序中,通过使用 Bean Validation 或是你自己定义的 constraint,例如 @NotNull, @Max, @ZipCode, 就可以确保数据模型(JavaBean)的正确性。constraint 可以附加到字段,getter 方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的 constraint。Bean Validation 是一个运行时的数据验证框架,在验证之后验证的错误信息会被马上返回。

后端在处理前端传过来的数据时,尽管前端表单已经加了校验逻辑,但是作为严谨考虑,在后端对接口传输的数据做校验也必不可少。 

二、SR303数据校验使用步骤


1、引入依赖

使用spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依赖

2、给参数对象添加校验注解

常见的注解

Bean Validation 中内置的 constraint
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

示例: 

 

3、接口参数前增加@Valid 开启校验

Controller 中需要校验的参数Bean前添加 @Valid 开启校验功能,紧跟在校验的Bean后添加一个BindingResult,BindingResult封装了前面Bean的校验结果。

/*** 保存*/@RequestMapping("/save")//@RequiresPermissions("product:brand:save")public R save(@Valid  @RequestBody BrandEntity brand, BindingResult result){if (result.hasErrors()){Map<String,String> map=new HashMap<>();//1.获取校验错误结果result.getFieldErrors().forEach((item)->{//获取到错误提示String message = item.getDefaultMessage();//获取到错误的属性名String field=item.getField();map.put(field,message);});return R.error(400,"提交数据不合法").put("data",map);}else{brandService.save(brand);}return R.ok();}

三、异常的统一处理


参数校验不通过时,会抛出 BingBindException 异常,可以在统一异常处理中,做统一处理,这样就不用在每个需要参数校验的地方都用 BindingResult 获取校验结果了。

可以在common中新建一个枚举用于存放我们异常类型

例:

package com.atguigu.common.exception;/*** @Description: 错误状态码枚举** 错误码和错误信息定义类* 1. 错误码定义规则为5为数字* 2. 前两位表示业务场景,最后三位表示错误码。例如:100001。10:通用 001:系统未知异常* 3. 维护错误码后需要维护错误描述,将他们定义为枚举形式* 错误码列表:*  10: 通用*      001:参数格式校验*      002:短信验证码频率太高*  11: 商品*  12: 订单*  13: 购物车*  14: 物流*  15:用户*****/public enum BizCodeEnum {UNKNOW_EXCEPTION(10000,"系统未知异常"),VAILD_EXCEPTION(10001,"参数格式校验失败"),TO_MANY_REQUEST(10002,"请求流量过大,请稍后再试"),SMS_CODE_EXCEPTION(10002,"验证码获取频率太高,请稍后再试"),PRODUCT_UP_EXCEPTION(11000,"商品上架异常"),USER_EXIST_EXCEPTION(15001,"存在相同的用户"),PHONE_EXIST_EXCEPTION(15002,"存在相同的手机号"),NO_STOCK_EXCEPTION(21000,"商品库存不足"),LOGINACCT_PASSWORD_EXCEPTION(15003,"账号或密码错误"),;private Integer code;private String message;BizCodeEnum(Integer code, String message) {this.code = code;this.message = message;}public Integer getCode() {return code;}public String getMessage() {return message;}
}

在exception包下创建一个异常类

例:

package com.atguigu.gulimall.product.exception;import com.atguigu.common.exception.BizCodeEnum;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;/*** Description: 集中处理异常**/
@Slf4j
/*
@RestController
@ControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
*/
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
public class GulimallExceptionControlleAdvice {//捕获异常指定异常 MethodArgumentNotValidException@ExceptionHandler(value = MethodArgumentNotValidException.class)public R handValidException(MethodArgumentNotValidException e){log.error("数据校验出现问题:{},异常类型:{}",e.getMessage(),e.getClass());BindingResult bindingResult = e.getBindingResult();Map<String,String> map=new HashMap<>();bindingResult.getFieldErrors().forEach((item)->{map.put(item.getField(),item.getDefaultMessage());});return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMessage()).put("data",map);}//任意异常类型@ExceptionHandler(value = Throwable.class)public R handException(Throwable throwable){return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMessage());}
}

 然后只需要校验的参数Bean前添加 @Valid 开启校验功能就可以了

例:

@RequestMapping("/save")public R save(@Valid @RequestBody BrandEntity brand){brandService.save(brand);return R.ok();}

四、分组解决校验


 新增和修改对于实体的校验规则是不同的,例如id是自增的时,新增时id要为空,修改则必须不为空;新增和修改,若用的恰好又是同一种实体,那就需要用到分组校验。

校验注解都有一个groups属性,可以将校验注解分组。

1、创建Groups 

从源码可以看出 groups 是一个Class<?>类型的数组,那么就可以创建一个Groups

 或

package com.xxxx.common.validator.group;/*** 新增数据 Group*/
public interface AddGroup {
}
package com.xxxx.common.validator.group;/*** 更新数据 Group**/public interface UpdateGroup {}

2、添加分组 

给参数对象的校验注解添加分组

例:

package com.atguigu.gulimall.product.entity;import com.atguigu.common.valid.AddGroup;
import com.atguigu.common.valid.ListValue;
import com.atguigu.common.valid.UpdateGroup;
import com.atguigu.common.valid.UpdateStatusGroup;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import org.hibernate.validator.constraints.URL;import javax.validation.constraints.*;/*** 品牌* */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {private static final long serialVersionUID = 1L;/*** 品牌id*/@NotNull(message = "修改必须指定品牌ID",groups = {UpdateGroup.class})@Null(message = "新增不能指定ID",groups = {AddGroup.class})@TableIdprivate Long brandId;/*** 品牌名*/@NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})private String name;/*** 品牌logo地址*/@NotBlank(groups = {AddGroup.class})@URL(message = "logo必须是一个合法的url地址",groups = {AddGroup.class,UpdateGroup.class})private String logo;/*** 介绍*/private String descript;/*** 显示状态[0-不显示;1-显示]*/@NotNull(groups = {AddGroup.class, UpdateStatusGroup.class})@ListValue(vals = {0,1},groups = {AddGroup.class, UpdateStatusGroup.class})private Integer showStatus;/*** 检索首字母*/@NotEmpty(groups = {AddGroup.class})//@Pattern自定义可以传入正则表达式@Pattern(regexp = "^[a-zA-Z]$",message = "检索字母必须是一个字母",groups = {AddGroup.class,UpdateGroup.class})private String firstLetter;/*** 排序*/@NotNull(groups = {AddGroup.class})@Min(value = 0,message = "排序必须大于等于0",groups = {AddGroup.class,UpdateGroup.class})private Integer sort;}

Controller 中原先的@Valid不能指定分组 ,需要替换成@Validated

@RequestMapping("/save")//@RequiresPermissions("product:brand:save")public R save(/*@Valid*/ @Validated({AddGroup.class}) @RequestBody BrandEntity brand/*, BindingResult result*/){/*if (result.hasErrors()){Map<String,String> map=new HashMap<>();//1.获取校验错误结果result.getFieldErrors().forEach((item)->{//获取到错误提示String message = item.getDefaultMessage();//获取到错误的属性名String field=item.getField();map.put(field,message);});return R.error(400,"提交数据不合法").put("data",map);}else{brandService.save(brand);}*/brandService.save(brand);return R.ok();}

五、自定义校验注解


虽然JSR303和springboot-validator 已经提供了很多校验注解,但是当面对复杂参数校验时,还是不能满足我们的要求,这时候我们就需要自定义校验注解。

假设一个字段规定使用0和1两种状态

点进去@NotNull查看 ,发现这些接口都有这些相同的信息

1、创建约束规则

我们可以跟着创建约束规则ListValue 

/*** @Description: 自定义注解**/@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class }) /*关联注解器-可以指定多个*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {// 默认会找ValidationMessages.propertiesString message() default "{com.atguigu.common.valid.ListValue.message}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };// 可以指定数据只能是vals数组指定的值int[] vals() default { };}

2、创建约束校验器

新建自定义校验器ListValuaConstraintValidator,并实现ConstraintValidator


/*** @Description: 校验器**/
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {private Set<Integer> set = new HashSet<>();/*** 初始化方法* @param constraintAnnotation*/@Overridepublic void initialize(ListValue constraintAnnotation) {int[] vals = constraintAnnotation.vals();for (int val : vals) {set.add(val);}}/*** 判断是否效验成功* @param value 需要效验的值* @param context* @return*/@Overridepublic boolean isValid(Integer value, ConstraintValidatorContext context) {//判断是否有包含的值boolean contains = set.contains(value);return contains;}}

3、自定义校验注解校验失败后的返回信息

新建配置文件ValidationMessages.properties,定义我们自定义校验注解校验失败后的返回信息

com.xxx.common.valid.ListValue.message =  必须提交指定参数

 例:

com.atguigu.common.valid.ListValue.message=必须提交指定的值

记得在刚刚编写好的自定义注解ListVaue中关联我们自定义的检验器

最后我们在使用@ListValue时就可以固定设定只能接收哪些值了

测试

六、总结


JSR303
*   1)、给Bean添加校验注解:javax.validation.constraints,并定义自己的message提示
*   2)、开启校验功能@Valid
*      效果:校验错误以后会有默认的响应;
*   3)、给校验的bean后紧跟一个BindingResult,就可以获取到校验的结果
*   4)、分组校验(多场景的复杂校验)
*         1)、  @NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})
*          给校验注解标注什么情况需要进行校验
*         2)、@Validated({AddGroup.class})
*         3)、默认没有指定分组的校验注解@NotBlank,在分组校验情况@Validated({AddGroup.class})下不生效,只会在@Validated生效;
*
*   5)、自定义校验
*      1)、编写一个自定义的校验注解
*      2)、编写一个自定义的校验器 ConstraintValidator
*      3)、关联自定义的校验器和自定义的校验注解
*      @Documented
* @Constraint(validatedBy = { ListValueConstraintValidator.class【可以指定多个不同的校验器,适配不同类型的校验】 })
* @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
* @Retention(RUNTIME)
* public @interface ListValue {
统一的异常处理
* @ControllerAdvice
*  1)、编写异常处理类,使用@ControllerAdvice。
*  2)、使用@ExceptionHandler标注方法可以处理的异常。

 结束!

相关文章:

【谷粒商城之JSR303数据校验和集中异常处理】

本笔记内容为尚硅谷谷粒商城JSR303数据校验和集中异常处理部分 目录 一、简介 二、SR303数据校验使用步骤 1、引入依赖 2、给参数对象添加校验注解 常见的注解 3、接口参数前增加Valid 开启校验 三、异常的统一处理 四、分组解决校验 1、创建Groups 2、添加分组 …...

限流算法(计数器、滑动时间窗口、漏斗、令牌)原理以及代码实现

文章目录前言1、计数器&#xff08;固定时间窗口&#xff09;算法原理代码实现存在的问题2、滑动时间窗口算法原理代码实现存在的问题3、漏桶算法原理代码实现存在的问题4、令牌桶算法原理代码实现最后本文会对这4个限流算法进行详细说明&#xff0c;并输出实现限流算法的代码示…...

C++回溯算法---图的m着色问题01

C回溯算法---图的m着色问题 图的m着色问题是指给定一个图以及m种不同的颜色&#xff0c;尝试将每个节点涂上其中一种颜色&#xff0c;使得相邻的节点颜色不相同。这个问题可以转化为在解空间树中寻找可行解的问题&#xff0c;其中每个分支结点都有m个儿子结点&#xff0c;最底层…...

ESP32 分区表

ESP32 分区表 1. 分区表概述 ESP32 针对 flash 进行划分&#xff0c;划分为不同的区域用作不同的功能&#xff0c;并在flash的 0x8000 位置处烧写了一张分区表用来描述分区信息。 分区表可以根据自己的需要进行配置&#xff0c;每一个分区都有其特定的作用&#xff0c;可根据…...

JJJ-2 init_IRQ

void __init init_IRQ(void) {int ret;if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)irqchip_init();else // init_irq成员定义为imx6ul_init_irq&#xff0c;会走这个分支machine_desc->init_irq(); if (IS_ENABLED(CONFIG_OF) && IS_ENABLED…...

【NLP实战】基于Bert和双向LSTM的情感分类【下篇】

文章目录前言简介第一部分关于pytorch lightning保存模型的机制关于如何读取保存好的模型完善测试代码第二部分第一次训练出的模型的过拟合问题如何解决过拟合后记前言 本文涉及的代码全由博主自己完成&#xff0c;可以随意拿去做参考。如对代码有不懂的地方请联系博主。 博主…...

程序设计方法学

体育竞技分析 问题分析 体育竞技分析 需求&#xff1a;毫厘是多少&#xff1f; 如何科学分析体育竞技比赛&#xff1f; 输入&#xff1a;球员的水平 输出&#xff1a;可预测的比赛成绩 体育竞技分析&#xff1a;模拟N场比赛 计算思维&#xff1a;抽象 自动化 模拟&am…...

Hadoop之Yarn篇

目录 ​编辑 Yarn的工作机制&#xff1a; 全流程作业&#xff1a; Yarn的调度器与调度算法&#xff1a; FIFO调度器&#xff08;先进先出&#xff09;&#xff1a; 容量调度器&#xff08;Capacity Scheduler&#xff09;&#xff1a; 容量调度器资源分配算法&#xff1…...

Spring Cloud Nacos使用总结

目录 安装Nacos服务器 服务发现与消费 服务发现与消费-添加依赖 服务发现-配置文件 服务发现-注解 服务发现-Controller 服务消费-配置文件 服务消费-注解与Ribbon消费代码 服务消费-运行 配置管理 配置管理-添加依赖 配置管理-配置文件 配置管理-注解 配置管理-…...

目标检测框架yolov5环境搭建

目前&#xff0c;目标检测框架中&#xff0c;yolov5 是很火的&#xff0c;它基于pytorch框架&#xff0c;集成opencv等框架&#xff0c;项目地址&#xff1a;https://github.com/ultralytics/yolov5&#xff0c;对我来说&#xff0c;机器学习、深度学习才开始接触&#xff0c;本…...

Vulnhub:Digitalworld.local (JOY)靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.130 信息收集 端口扫描 nmap -A -v -sV -T5 -p- --scripthttp-enum 192.168.111.130 使用enum4linux枚举目标smb服务&#xff0c;发现两个系统用户 enum4linux -a 192.168.111.130 ftp可以匿名登陆&#xff…...

STL源码剖析-六大部件, 部件的关系,复杂度, 区间表示

C标准库-体系结构与内核分析 根据源代码来分析 介绍 自学C侯捷老师的STL源码剖析的个人笔记&#xff0c;方便以后进行学习&#xff0c;查询。 为什么要学STL&#xff1f;按侯捷老师的话来说就是&#xff1a;使用一个东西&#xff0c;却不明白它的道理&#xff0c;不高明&…...

总有一个可用的连接,metaIPC1.2进入智能连接新时代

概述 metaIPC有1.0和2.0两个产品系列&#xff0c;2.0版本是可视对讲IPC&#xff0c;1.0新版本1.2在全面兼容ICE规范基础上进行了扩展&#xff0c;使metaIPC1.2进入智能化连接新时代。 metaIPC1.2在host/stun/turn/srs/zlm/janus/freeswitch等p2p/sfu/mcu进行全方位连通测试&a…...

棋盘问题c

在一个给定形状的棋盘&#xff08;形状可能是不规则的&#xff09;上面摆放棋子&#xff0c;棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列&#xff0c;请编程求解对于给定形状和大小的棋盘&#xff0c;摆放k个棋子的所有可行的摆放方案C。 Input …...

华纳云:Linux系统下怎么创建普通用户并更改用户组

本篇内容主要讲解“Linux系统下怎么创建普通用户并更改用户组”&#xff0c;感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷&#xff0c;实用性强。下面就让小编来带大家学习“Linux系统下怎么创建普通用户并更改用户组”吧! 要求 项目做权限管理&#xff0c;不用root部…...

「她时代」背后的欧拉力量

2018年大热电视剧《北京女子图鉴》&#xff0c;讲述了一群在北京打拼的职业女性&#xff0c;她们背井离乡&#xff0c;被现实包裹&#xff0c;被压力、责任困扰&#xff0c;但依旧用倔强的个性、不屈的进取心和深厚的知识技能努力营造、交织出一片励志的天空&#xff0c;既激昂…...

kubespray v2.21.0 在线部署 kubernetes v1.24.0 集群【2】

文章目录创建 虚拟机模板虚拟机名称配置静态地址配置代理yum 配置配置主机名安装 git安装 docker安装 ansible配置内核参数安装 k8s定制安装新增节点配置主机名配置代理配置互信更新 inventory报错kubespray v2.21.0 部署 kubernetes v1.24.0 集群 【1】在 Rocky linux 8.7 使用…...

聚焦运营商信创运维,美信时代监控易四大亮点值得一试!

2021年11月《“十四五”信息通信行业发展规划》提出&#xff0c;到2025年&#xff0c;我国将建立高速泛在、集成互联、智能绿色、安全可靠的新型数字基础设施体系。 此《规划》让我国运营商信创进一步加速&#xff0c;中国移动、中国电信、中国联通等都先后加入信创大军&#x…...

[python刷题模板] 博弈入门-记忆化搜索/dp/打表

[python刷题模板] 博弈入门-记忆化搜索/dp/打表 一、 算法&数据结构1. 描述2. 复杂度分析3. 常见应用4. 常用优化二、 模板代码1. 打表贪心的博弈2. 464. 我能赢吗3. Nim游戏--最最基础版n1。三、其他四、更多例题五、参考链接一、 算法&数据结构 1. 描述 博弈一直没…...

I2C通信

一、理论上了解I2C时序 I2C写数据时序如图&#xff1a; 通过解析器解析I2C通信如上图&#xff08;SCL和SDA反了&#xff09;。 1---起始信号 2、3---应答信号ACK 5---停止信号 起始信号&#xff1a;SCL线是高电平时&#xff0c;SDA线从高电平向低电平切换。 停…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...