Java 无法覆盖Spring MVC中的ConstraintValidator默认消息

Java 无法覆盖Spring MVC中的ConstraintValidator默认消息,java,spring-mvc,bean-validation,hibernate-validator,Java,Spring Mvc,Bean Validation,Hibernate Validator,在使用Spring验证时,我遇到了覆盖默认ConstraintValidator消息的问题 我有一个自定义messages.properties文件,其中包含以下值: NotNull=This field is mandatory BankHoliday=You cannot select a bank holiday 我对BankHoliday的注释如下: @Documented @Constraint(validatedBy = BankHolidayValidator.class) @T

在使用Spring验证时,我遇到了覆盖默认ConstraintValidator消息的问题

我有一个自定义messages.properties文件,其中包含以下值:

NotNull=This field is mandatory
BankHoliday=You cannot select a bank holiday
我对BankHoliday的注释如下:

@Documented
@Constraint(validatedBy = BankHolidayValidator.class)
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BankHoliday {

    String message() default "{BankHoliday}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
public class BankHolidayValidator implements ConstraintValidator<BankHoliday, Date> {

@Override
public void initialize(BankHoliday bankHoliday) { }

@Override
public boolean isValid(Date date, ConstraintValidatorContext cxt) {

    if(date == null) {
        cxt.disableDefaultConstraintViolation();
        cxt.buildConstraintViolationWithTemplate("{NotNull}").addConstraintViolation();
        return false;
    } else if (isBankHoliday(date)) {
        return false;
    } else {
        return true;
    }
}
我的控制器看起来像:

@RequestMapping(value="/new/request", method = RequestMethod.POST)
public String putNewRequest(@Valid @ModelAttribute("request") Request request, BindingResult bindingResult, Map<String, Object> map) {

    if (bindingResult.hasErrors()) {

        // return them back

    } else {

        // process the request
    }
}
@RequestMapping(value=“/new/request”,method=RequestMethod.POST)
公共字符串putNewRequest(@Valid@modeldattribute(“request”)请求、BindingResult、BindingResult、Map){
if(bindingResult.hasErrors()){
//把它们还给我
}否则{
//处理请求
}
}
但是,当用户未填充此字段时,他们看到的错误消息是“您无法选择银行假日”,而不是“此字段为必填字段”。浏览完代码后,我可以看到cxt.disableDefaultConstraintViolation()行肯定正在被调用,并且正在添加{NotNull}约束验证,但是用户总是看到默认消息


我尝试过用“测试消息”替换“{NotNull}”,但这也不起作用。有人能给我指出这不起作用的正确方向吗?

我已经研究了我自己的代码(正在起作用),唯一的区别是您没有调用
addNode()
方法,所以我建议调用它:

cxt.disableDefaultConstraintViolation();
cxt.buildConstraintViolationWithTemplate("{NotNull}")
   .addNode("desiredBookingDate")
   .addConstraintViolation();

但是,IMHO,您将走错方向:验证器应该只负责一种类型的验证。要将字段标记为必填字段,最好使用
@NotNull
注释。您可能会面临另一个问题:空字符串将始终通过此类约束。为了解决这个问题,在春季,您应该使用
StringTrimmerEditor
emptyAsNull
=
true
参数,在验证之前将空字符串转换为
null
值。

可能有点晚了。。但是我会把我的答案贴给其他人

显然,它与默认消息常量的名称有关

{BankHoliday} could be replaced with {bank.holiday} (or any other key) and it will work.

当然。。同时重命名属性文件中的消息键。。它不喜欢将确切名称作为接口本身的消息。

感谢您的回复。我尝试了
cxt.buildConstraintViolationWithTemplate(“{NotNull}”).addNode(“desiredBookingDate”).addConstraintViolation()但我现在得到一个异常“JSR-303验证属性'desiredBookingDate.desiredBookingDate'没有对应的Spring数据绑定访问器”。另外,
addNode()
现在已被弃用,因此我尝试将其替换为
addPropertyNode()
,但失败了,出现了相同的错误。这是另一个错误,意味着具有desiredBookingDate属性的对象没有相应的setter(
void setDesiredBookingDate(Date)
).您是否尝试过纯Bean验证的示例?基本上创建一个验证器实例并验证两个不同的实例,这两个实例应该返回不同的消息。我基本上想知道问题是发生在Bean验证(又称Hibernate验证程序)中还是发生在Spring集成中(可能消息是缓存的!?)。这就是说,我同意-使用约束组合而不是动态更改消息更符合Bean验证的精神-我已经研究了约束组合,这更合适,感谢指针。它有效,但添加了{bank.holiday}ValidationMessages.properties中的消息,而不是messages.properties中的消息
{BankHoliday} could be replaced with {bank.holiday} (or any other key) and it will work.