目录

一.触发验证实例现象分析

1.前 端:

2.后 端:

二.参数验证全流程解析

1.前    端:

1.1输入参数:岗位名称

1.2点击确认

1.3请求发送

2.后   端:

2.1请求到达并接收

2.2参数校验

2.3参数校验的实体

2.4校验结果--异常处理​编辑

2.5返回给前端后响应拦截

三.自定义【参数验证】的注解

1.新增自定义注解,设置自定义校验器

2.自定义校验器,实现接口

3.实体类使用注解

4.功能验证


触发参数验证异常的泳道图

一.触发验证实例现象分析

1.前 端:

当我们在ruoyi前端进行输入异常的操作(岗位名称输入很多字符)时会弹出如下提示。

2.后 端:

查看后端日志后根据错误时间和erro提示可知晓异常错误为传入的值太长了,超出了限定范围,所以会拒绝确认抛出提示信息。

根据日志错误提示去查看一下ruoyi中实际的出错代码段

2.1用于抛出异常的路径:ruoyi\RuoYi-Vue\ruoyi-framework\src\main\java\com\ruoyi\framework\web\exception\GlobalExceptionHandler.java

2.2出错的方法的路径:ruoyi\RuoYi-Vue\ruoyi-admin\src\main\java\com\ruoyi\web\controller\system\SysPostController.java

2.3抛出提示信息的路径:ruoyi\RuoYi-Vue\ruoyi-system\src\main\java\com\ruoyi\system\domain\SysPost.java

那么现在根据后端的日志进行查看后可以大致知道出现这个异常的原因:前端输入岗位名称后传给后端对应岗位添加的方法(syspostcontroller.add()),在执行具体的逻辑前会通过@validated进行参数验证,验证失败后执行@exceptionhandler把message错误信息抛出。


以上是一个大致的输入信息时的参数验证流程,

-那么他们前端之间是如何互相关联返回这个code:500?

-前端又是如何传入这个参数给后端触发验证?

-具体是通过什么进行验证?

-是如何定义这个验证的执行逻辑?


二.参数验证全流程解析

1.前    端:

1.1输入参数:岗位名称

我们开始做了一个操作在“添加岗位”的弹窗表单里输入了岗位名称( form.postName )长度>50。

1.2点击确认

当我们点击前端的“确 认”按钮后@click进行”事件监听“会执行“submitfrom”方法↓↓↓。

这里的this.$refs["form"].validate(valid => { ... })在该页面的表单校验规则 rules 仅校验“是否为空”

:rules属性绑定了rules对象。这就建立了表单数据和校验规则之间的关联。

1.3请求发送

执行完是否为空的校验后会去执行addpost(),该方法在 ruoyi-ui/src/api/system/post.js 中将数据以 POST /system/post 发送到后端。

2.后   端:

2.1请求到达并接收

请求到达控制器SysPostController.java 的add接口​​​​​​

2.2参数校验

在入参时有@validated这个注解


在spring boot中可以用@Validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。


所以Spring 在进入方法体前会对 SysPost 对象进行 Bean Validation。

2.3参数校验的实体

这段在 SysPost 上的注解就是这个接口的“参数校验规则”,定义在实体上的约束,进入控制器方法前会被执行。

当输入的岗位名称长度>50,触发 @Size 校验不通过,Spring 抛出 MethodArgumentNotValidException ,方法体里的唯一性校验等逻辑不再继续执行。

2.4校验结果--异常处理

全局异常处理器GlobalExceptionHandler捕获到上面抛出的MethodArgumentNotValidException

 方法: handleMethodArgumentNotValidException 会进行如下行为
- 记录错误日志(控制台里看到的 error 堆栈),从异常中取第一个字段错误的默认消息(这里就是“岗位名称长度不能超过50个字符”),并返回一个 AjaxResult.error(message) 。
- 返回给前端的响应体是统一格式的 JSON,包含 code (通常为 500 )和 msg (校验消息)。

2.5返回给前端后响应拦截

前端接收并提取返回的code进行判断

当 code === 500 ,执行 Message({ message: msg, type: 'error' }) ,弹出错误提示框。

同时 Promise.reject(new Error(msg)) ,使页面里对 addPost(...).then(...) 的成功回调不执行,页面不会走“新增成功”的分支。

最终你看到前端弹出的错误消息(内容就是后端返回的 msg ),以及后端控制台的 error 日志。

三.自定义【参数验证】的注解

根据后台手册 | RuoYi我们也可以自定义一个注解校验

1.新增自定义注解,设置自定义校验器

首先新建文件NoDigits.java(自定义注解定义,【声明层】)

package com.ruoyi.common.validation;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Documented
@Constraint(validatedBy = NoDigitsValidator.class)
@Target({ FIELD, METHOD, PARAMETER, ANNOTATION_TYPE })
@Retention(RUNTIME)
public @interface NoDigits {
    String message() default "岗位名称不能有数字";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

实现的核心:

-@Constraint(validatedBy = NoDigitsValidator.class)  指定这个注解的逻辑由 NoDigitsValidator 类来执行。

-@Retention(RUNTIME)  保证这个注解在运行时仍然存在(Bean Validation 框架才能识别)。

-message()  自定义验证失败时的提示信息。

其余参考文档它自定义的Xss注解补充即可

2.自定义校验器,实现接口

package com.ruoyi.common.validation;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class NoDigitsValidator implements ConstraintValidator<NoDigits, String> {

    @Override
    public void initialize(NoDigits constraintAnnotation) {
        // 无需初始化
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 让 @NotBlank 处理空值,这里为空返回 true
        if (value == null || value.trim().isEmpty()) {
            return true;
        }
        // 包含任意数字即不合法
        return !value.matches(".*\\d+.*");
    }
}

实现的核心:

-ConstraintValidator< , >  这是一个接口,其中第一个参数是对应的注解类型,第二个参数是被校验的字段类型。

-isValid() 返回   true是校验通过/false是校验失败(触发错误信息)

3.实体类使用注解

在syspost.java中添加新定义的注解即可

4.功能验证

原岗位名称可以输入数字,现在新增了自定义的参数验证后输入数字出现错误提示。

查看ruoyi后端日志也抛出error,触发参数验证异常。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐