如何在DTO验证注解中嵌入messages.properties的字段名称参数?
实现通用校验消息与国际化字段名的结合
方法一:利用Hibernate Validator的嵌套消息插值(最简单)
这种方式无需额外编写自定义代码,直接通过内置占位符实现字段名的国际化替换:
- 修改国际化消息文件
保持src/main/resources/lang/messages.properties内容,仅调整通用校验消息的占位符写法:
# 用${property}嵌套解析字段名对应的国际化文本 field.NotBlank=Polje {${property}} je obavezno. # 字段名的国际化配置 email=imejl adresa
这里的{property}是Hibernate Validator提供的内置占位符,会被替换为当前校验的字段名(比如email),随后${email}会进一步解析为对应的国际化文本imejl adresa。
- 修改DTO的校验注解
直接在@NotBlank中引用通用消息即可:
public class RegisterDTO { @NotBlank(message = "{field.NotBlank}") private String email; // 其他字段... }
当email字段为空时,最终生成的错误消息为:Polje imejl adresa je obavezno.
方法二:自定义校验注解(灵活指定国际化键)
如果字段名和国际化键不一致(比如字段名为userEmail,但国际化键是email),可以通过自定义注解实现:
- 创建自定义校验注解
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = CustomNotBlankValidator.class) public @interface CustomNotBlank { String message() default "{field.NotBlank}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; // 用于指定字段的国际化键 String fieldKey(); }
- 实现校验器(复用默认NotBlank逻辑)
public class CustomNotBlankValidator implements ConstraintValidator<CustomNotBlank, String> { private final org.hibernate.validator.internal.constraintvalidators.bv.NotBlankValidator delegate = new org.hibernate.validator.internal.constraintvalidators.bv.NotBlankValidator(); @Override public void initialize(CustomNotBlank annotation) { // 初始化委托校验器 delegate.initialize(new NotBlank() { @Override public String message() { return annotation.message(); } @Override public Class<?>[] groups() { return annotation.groups(); } @Override public Class<? extends Payload>[] payload() { return annotation.payload(); } }); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { // 替换消息中的{fieldKey}占位符为指定的国际化键 context.disableDefaultConstraintViolation(); context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()) .addParameter("fieldKey", annotation.fieldKey()) .addConstraintViolation(); return delegate.isValid(value, context); } }
- 调整国际化消息文件
field.NotBlank=Polje {fieldKey} je obavezno. email=imejl adresa
- 在DTO中使用自定义注解
public class RegisterDTO { @CustomNotBlank(fieldKey = "{email}", message = "{field.NotBlank}") private String userEmail; // 其他字段... }
必备配置:确保国际化生效
需在Spring配置中正确初始化消息源和校验器:
@Configuration public class LocalizationConfig { @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasenames("lang/messages"); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } @Bean public LocalValidatorFactoryBean validator() { LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); validator.setValidationMessageSource(messageSource()); return validator; } }
内容的提问来源于stack exchange,提问作者IgorArnaut
相关产品推荐
相关产品推荐

