【问题标题】:Build own new message from BindingResult从 BindingResult 构建自己的新消息
【发布时间】:2021-04-06 06:37:46
【问题描述】:

我想向您咨询有关 BindingResult 的问题。下面看看我的情况。

我的messages.properties存储错误信息如下

error.required=Please input {0}

我的控制器拒绝了 2 个字段,错误如下

bidingResult.rejectValue("field1", "error.required", new Object[]{"Field1"}, null);
bidingResult.rejectValue("field2", "error.required", new Object[]{"Filed2"}, null);

我的视图使用 Thymeleaf 语法​​提取消息,如下所示

<div th:each="err : ${#fields.errors('*')}" th:text="${err}"></div>

结果将显示如下2条消息

Please input Field1
Please input Field2

我的问题是我可以通过 BindingResult 创建一个新的消息对象来显示这样的消息

Please input Field1 and Field2

我想将相同的错误合并在一起并连接消息参数

【问题讨论】:

    标签: spring spring-boot thymeleaf


    【解决方案1】:

    最简单的方法是在对象级别创建自定义验证器。从自定义注释开始:

    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;
    
    @Target(ElementType.TYPE) 
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = BothFieldsPresentValidator.class) 
    public @interface BothFieldsPresent {
          String message() default "{BothFieldsPresent}";
          Class<?>[] groups() default {};
          Class<? extends Payload>[] payload() default {};
      }
    

    接下来,创建自定义验证器:

    public class BothFieldsPresentValidator implements ConstraintValidator<BothFieldsPresent, MyObject> {
    
      public boolean isValid(MyObject myObject, ConstraintValidatorContext context) {
        
        if( myObject.getField1() == null && myObject.getField2() == null ) {
          context.disableDefaultConstraintViolation();
          context.buildConstraintViolationWithTemplate("{BothFieldsPresent}")
                 .addConstraintViolation()
          return false;
        }
    
        return true;
      }
    }
    

    将新的自定义注释添加到您的 MyObject 类:

    @BothFieldsPresent
    public class MyObject {
      ...
    }
    

    在您的控制器中,执行以下操作:

    @PostMapping
    public String doPost(@Valid @ModelAttribute("myObject") MyObject myObject, BindingResult bindingResult, Model model) {
      if( bindingResult.hasErrors() ) {
        return "template-name"
      }
    
      service.doSomething(myObject);
    
      return "redirect:/somewhere"
    }
    

    将此添加到messages.properties:

    BothFieldsPresent=Please input Field1 and Field2
    

    【讨论】:

    • 感谢您的支持,但由于我的逻辑检查逻辑复杂,我无法使用自定义约束验证器来验证表单级别。我在服务、常用工具、自定义验证器上都有拒绝字段。此外,实际上消息参数是动态的。
    • 我很抱歉我的一些细节。我之所以有拒绝字段,是因为在我看来,检查每个输入字段是否有拒绝。如果该输入字段被拒绝,它将通过将背景设置为红色来突出显示。
    猜你喜欢
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多