参数验证(Parameter Validation)是指在程序中对输入参数进行检查和确认,以确保这些参数满足预期的要求和约束。在软件开发中,尤其是函数或方法调用时,传递给函数的参数必须是有效的,参数验证有助于确保程序能够正确运行,并防止潜在的错误或安全漏洞。
参数验证的目的
防止无效输入:确保传递给函数或方法的参数是合理且符合预期格式的。例如,确保数值参数不为负数、字符串不为空、日期格式正确等。
增强程序健壮性:通过验证输入参数,减少运行时错误,提升代码的鲁棒性。
防止安全漏洞:一些恶意输入可能被用来攻击应用程序,比如SQL注入、跨站脚本攻击(XSS)等。通过验证输入,能够有效地防止这些攻击。
提高代码可维护性:明确的参数验证可以帮助开发者更清楚地了解函数的期望行为和约束,从而避免因传递不合法参数而引发的问题。
触发验证抛出异常
本示例以RuoYi-Vue-3.28.0 岗位管理功能中修改角色名称的长度验证为例
1.触发方式和前端现象
2.后端现象
IDEA 的日志输出含如下Log:
14:05:16.629 [http-nio-8080-exec-42] WARN o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - [logException,208] - Resolved
[org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.ruoyi.common.core.domain.AjaxResult
com.ruoyi.web.controller.system.SysRoleController.edit(com.ruoyi.common.core.domain.entity.SysRole): [Field error in object 'sysRole' on field 'roleName': rejected value
[普通角色aerdfgfdsgsdffgsdfgdmalsdlkasmdaksmdlkasmdlmasldkmalksdmkalsmdlaksmdlamsdlkmasldmas]; codes [Size.sysRole.roleName,Size.roleName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [sysRole.roleName,roleName]; arguments []; default message [roleName],30,0]; default message [角色名称长度不能超过30个字符]] ]
3,源码分析
1.前端代码
rules中限制不能输入空
确认提交按钮中的解析
后端返回的请求码,后端返回信息后,前端的处理逻辑,返回值为500时,输出错误提示message框
2.后端代码
找到我们在后端角色管理界面的代码,如下图:
找到我们的编辑处理函数下
进而可以,根据注解,理解我们下面
异常处理方法如下:
使用的是如下的自定义异常
3.报错分析
角色名称修改报错,分析逻辑总结:
1.修改角色名称名称长度超过30
2.点击确定与后台交互,请求URI:/system/role
3.后台检测到SysRole 的参数SysPost 不符合要求,则抛出异常类型MethodArgumentNotValidException
4.异常被全局异常处理器捕获,返回message 给到前端,且错误码是500
5.前端路由截获错误码500 的信息,进行处理显示message 内。
2,自定义注解校验
1.添加依赖
在ruoyi-common目录下的pom.xml中引入验证validation依赖
<!-- 引入验证validation依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.创建一个接口和一个类
这是项目的路径ruoyi-common\src\main\java\com\ruoyi\common\core\domain\entity
在接口中的代码为
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();
}
}
在SysRole中,添加验证数字的注解
完成后运行
欸嘿,我们发现可以正常使用
总结
自定义注解校验是通过自定义注解和校验器来对数据进行验证的一种方式,常用于增强代码的可维护性和可读性。