You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在DTO验证注解中嵌入messages.properties的字段名称参数?

实现通用校验消息与国际化字段名的结合

方法一:利用Hibernate Validator的嵌套消息插值(最简单)

这种方式无需额外编写自定义代码,直接通过内置占位符实现字段名的国际化替换:

  1. 修改国际化消息文件
    保持src/main/resources/lang/messages.properties内容,仅调整通用校验消息的占位符写法:
# 用${property}嵌套解析字段名对应的国际化文本
field.NotBlank=Polje {${property}} je obavezno.

# 字段名的国际化配置
email=imejl adresa

这里的{property}是Hibernate Validator提供的内置占位符,会被替换为当前校验的字段名(比如email),随后${email}会进一步解析为对应的国际化文本imejl adresa。

  1. 修改DTO的校验注解
    直接在@NotBlank中引用通用消息即可:
public class RegisterDTO {
    @NotBlank(message = "{field.NotBlank}")
    private String email;

    // 其他字段...
}

当email字段为空时,最终生成的错误消息为:Polje imejl adresa je obavezno.


方法二:自定义校验注解(灵活指定国际化键)

如果字段名和国际化键不一致(比如字段名为userEmail,但国际化键是email),可以通过自定义注解实现:

  1. 创建自定义校验注解
@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();
}
  1. 实现校验器(复用默认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);
    }
}
  1. 调整国际化消息文件
field.NotBlank=Polje {fieldKey} je obavezno.

email=imejl adresa
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 22:34:53