目录
👋前言
👀一、环境准备
📫二、代码实现
2.1 Validation 自定义验证类
2.2 自定义注解代码实现
💞️三、测试
🌱四、章末
👋前言
小伙伴们大家好,最近在和一位读者讨论国际化上下文工具使用的时候,遇到了另外一个问题
问题场景如下,项目引入了 Validation 依赖,该依赖提供请求参数运行时校验,比如@NotBlank,@NotEmpty 等,并且这些注解可以指定校验不通过时的返回信息,但是将返回信息用国际化上下文表示时发现并不起作用,网上搜寻了下也是找到了原因,因为原生的 Bean Validation 注解不支持结合国际化上下文,但还是有方法实现的,因为 Validation 框架给用户提供了自定义验证器的接口,可以从该入口下手,详细如下:
👀一、环境准备
注:本地项目基于 SpringBoot 框架,可以通过创建项目时使用 SPring intialor 快速创建或者普通的 java 项目然后手动添加启动类和配置文件.yml
1.1 Validation 依赖引入
该操作是通过 maven 工具将依赖引入本地,以便使用提供的校验注解;该操作之前有学习过,使用比较简单,文章链接如下
【Javax.Validation】✈️整合 SpringBoot 实现运行时的参数校验_javax.validation spring boot-CSDN博客
1.2 国家化上下文 i18n 的搭建
该过程比较简单,可以参考我之前的文章,链接如下:
MessageUtils 实现返回信息多语言支持-CSDN博客
📫二、代码实现
2.1 Validation 自定义验证类
Validation 提供了 ConstraintValidator 接口供用户自定义实现,需要在泛型中声明搭配哪一个注解使用,以及该自定义验证器针对哪种数据格式使用
import com.example.demo.aop.CustomNotBlank;
import com.example.demo.common.component.MessageUtils;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* @author HuangBen
*/
public class CustomNotBlankValidator implements ConstraintValidator<CustomNotBlank, String> {
private String messageKey;
@Override
public void initialize(CustomNotBlank constraintAnnotation) {
messageKey = constraintAnnotation.message();
}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
if (s == null || s.trim().isEmpty()) {
String msg = MessageUtils.get(messageKey);
constraintValidatorContext.buildConstraintViolationWithTemplate(msg)
.addConstraintViolation()
.disableDefaultConstraintViolation();
return false;
}
return true;
}
}
2.2 自定义注解代码实现
这里定义注解的时候指定了该注解可以用作成员变量(FIELD)和 方法参数上面(PARAMTER),另外就是将该注解和自定义校验器通过 @Constraint 关联起来,还有一个注解标注运行时保留
给该接口一个方法,用来在使用注解时没有指定消息 key (国际化上下文的 key)值的情况下使用默认的key
groups 和 payload 方法是 Java Bean Validation 规范的一部分,用于支持复杂的验证场景。这里没有使用,但还是需要保留,因为要符合规范和确保注解正确工作
import com.example.demo.utils.CustomNotBlankValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author HuangBen
*/
@Constraint(validatedBy = CustomNotBlankValidator.class)
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomNotBlank {
String message() default "{test.msg.info}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
💞️三、测试
3.1 测试实体类
3.2 简单创建一个测试请求路径
注意这里搭配 Validation 框架使用时需要在被校验的参数前面加上 @Valid 注解否则不会判断
3.3 APIPost 模拟请求测试
使用接口测试工具来模拟请求检测注解是否生效
请求体 use.name 为 null 时 ,中文环境下结果如下
请求体 use.name 为 null 时,英文环境下的结果
请求体 use.name 为 正常格式 时,结果如下
🌱四、章末
文章到这里就结束了~