目录
引言
RuoYi-Vue 触发参数验证,可以有效地对应用程序中的数据进行验证,确保应用的安全与健壮,传入系统的数据符合预期的格式和规则,从而提高系统的稳定性和安全性。
一、参数验证
1.1参数验证是什么
参数验证是指在软件开发过程中,对程序接收到的输入数据(参数)进行检查的过程,以确保这些数据符合预期的格式、类型和范围。参数验证是提高软件质量、安全性和用户体验的重要步骤之一。它可以帮助开发者提前发现并处理潜在的问题,比如非法输入导致的安全漏洞或系统崩溃。
1.2参数验证的重要性
- 安全性:防止恶意用户通过构造特殊输入来攻击系统,例如SQL注入攻击。
- 健壮性:确保应用能够正确处理各种异常情况,避免因错误输入而导致的程序异常或崩溃。
- 用户体验:即时反馈给用户关于输入错误的信息,有助于用户快速修正问题,提供更好的交互体验。
- 业务逻辑一致性:保证数据满足业务规则要求,维护系统的内部一致性。
1.3参数验证的内容
- 非空验证:检查字符串或其他集合类型是否为空。
- 格式验证:如邮箱地址、电话号码等特定格式的匹配。
- 长度限制:定义字符串的最大长度或最小长度。
- 数值范围:确定数值型参数必须处于某个合理的区间内。
- 唯一性约束:确保某些字段值在整个数据库中是唯一的,比如用户名。
- 正则表达式:使用正则表达式来更精确地控制字符串模式。
- 枚举值:确保提供的值属于预定义的一组选项之中。
1.4实现方式
参数验证可以在多个层次上实现:
- 前端验证:利用JavaScript等技术在客户端直接执行验证逻辑,减少不必要的服务器请求。
- 后端验证:即使前端已经进行了验证,在服务端仍然需要再次验证,因为前端验证可以被绕过。
- 使用框架提供的注解(如Spring MVC中的
@Valid
,@NotNull
等)。 - 自定义验证器。
- 在业务逻辑层手动编写验证逻辑。
- 使用框架提供的注解(如Spring MVC中的
小结
总之,参数验证是一种预防性的措施,通过在数据进入应用程序核心之前对其进行检查,可以大大提高系统的可靠性与安全性。
二、触发验证抛出异常
(ps例子:在RuoYi-Vue岗位管理中添加岗位)
触发方式:进入首页-->系统管理-->岗位管理-->新增,输入大于50个字符(123456789123456789123456789123456789123456789123456789123456789)
反馈:弹出输入大于50个字符长度
2.1后端现象
我们会看到IDEA中的RUN RAB输出如图例的log
三、源码分析
3.1源码分析
3.1.1前端代码
必须填写,若没填写会显示message提示框
确定后,通过updatePost函数对URI为/system/role发起HTTP POST操作,请求body为data
返回值为500时,输出错误提示message框(岗位名称长度不能超过50个字符)
3.1.2后端代码
在后端中,如果两个限制条件不满足,就会返回code:500给前端
异常处理:
3.1.3报错处理
岗位名称修改报错,分析逻辑总结:
1.添加前端岗位名称长度超过50
2.点击确定与后台交互,请求URI:/system/post
3.后台检测SysRole的参数SysPost不符合要求,会抛出异常类型
(MethodArgumentNotValidException)
4.异常被全局异常处理器捕获,返回message给到前端,且错误码是500
5.前端路由截获错误码code:500的信息,进行处理显示message内容
四、自定义注解校验
4.1添加依赖
在ruoyi-common目录下的pom.xml中引入验证validation依赖
<!-- 引入验证validation依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
4.2创建一个新的接口和一个类
接口中的代码
package com.ruoyi.common.core.domain.entity;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
* 自定义注解 @NotNumber,用于验证字段值是否包含数字。
*
* @author [SH]
* @version 1.0
*/
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {NotNumberValidator.class})
public @interface NotNumber {
/**
* 默认错误消息,当验证失败时返回此消息。
* @return 默认错误消息
*/
String message() default "输入的内容不允许包含数字";
/**
* 分组,用于指定验证分组。
* @return 验证分组
*/
Class<?>[] groups() default {};
/**
* 负载,用于传递额外的信息。
* @return 负载
*/
Class<? extends Payload>[] payload() default {};
}
在类中实现接口,所需的代码
package com.ruoyi.common.core.domain.entity;
import com.ruoyi.common.utils.StringUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 验证器类 NotNumberValidator,用于实现 @NotNumber 注解的验证逻辑。
*
* @author [你的名字]
* @version 1.0
*/
public class NotNumberValidator implements ConstraintValidator<NotNumber, String> {
/**
* 定义正则表达式模式,用于匹配数字。
*/
private final String PATTERN = "^[0-9]*$";
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
// 如果值为空或为空字符串,返回 false
if (StringUtils.isBlank(value)) {
return false;
}
// 调用 containsHtml 方法检查字符串是否包含数字
return !containsHtml(value);
}
/**
* 检查字符串是否包含数字。
*
* @param value 需要检查的字符串
* @return 如果字符串包含数字,返回 true;否则返回 false
*/
public boolean containsHtml(String value) {
// 创建正则表达式模式对象
Pattern pattern = Pattern.compile(PATTERN);
// 创建匹配器对象
Matcher matcher = pattern.matcher(value);
// 返回匹配结果
return matcher.matches();
}
}
4.3在SysRole中,添加验证数字的注解
4.4验证是否成功
当我们看到上方我们所需要的提示出现时,说明成功
五、总结
参数验证是确保软件接收的数据符合预期格式和规则的过程,对于提高系统安全性、健壮性和用户体验至关重要。它涉及检查数据的非空性、格式正确性、长度限制及数值范围等,并可在前端和后端实施。通过使用注解、自定义验证器或业务逻辑中的手动检查来实现,有效防止非法输入导致的安全漏洞和程序异常。