【问题标题】:How can I validate a field of a object on my domain object in Spring MVC?如何在 Spring MVC 中验证我的域对象上的对象字段?
【发布时间】:2012-04-19 11:52:39
【问题描述】:

我有一个对象 Foo 包含对对象 Bar 的引用,该对象引用了对象 Baz,并且为了使 Foo 有效,Bar 必须有一个有效的、非-null 引用Baz

问题是Bar 不需要 需要一个有效的、非空的Baz 才有效,所以我不能简单地将验证放在那里,我需要它在Foo 之内。

这是我正在谈论的类结构的简单伪版本:

class Foo {
    // Bar needs to have a valid Baz. Something like this would be ideal:
    // @HasAValidBaz(message="Baz is required")
    Bar bar;   
}

class Bar {
    // Baz can be null and Bar will still be valid
    // But if there _is_ a Baz, it needs to be valid
    Baz baz;
}

class Baz {
    @NotBlank(message="My String is required")
    String myString;
}

我知道我可以使用类级别的自定义验证注释来做到这一点,但问题是那些错误对象和相应的消息适用于类实例而不是字段实例,我需要能够轻松显示错误正确表单字段旁边的消息。

有什么好的方法可以做到这一点,还是我坚持在控制器中实现这个验证?

【问题讨论】:

    标签: java validation spring-mvc annotations


    【解决方案1】:

    注释很好,但在这种情况下可能不合适。问题是在实际类上标记了注释,这意味着你不能在同一个类上真正有两种类型的验证注释——这似乎是你的问题。使用老式的 Spring MVC 方法来实现 Spring Validator 类可能更适合您。这是一个例子:

    public class FooValidator implements Validator {
    
        @Override
        public boolean supports(Class<?> clazz) {
            return Foo.class.equals(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
    
            Foo foo = (Foo) target;
    
            if(foo.getBar() == null) {
                errors.rejectValue("bar", "bar[emptyMessage]");
            }
            else if(foo.getBar().getBaz() == null){
                errors.rejectValue("bar.baz", "bar.baz[emptyMessage]");
            }
        }
    }
    

    您的 Spring 控制器仍然与使用注释几乎相同:

    @Controller
    public class FooController {
    
        @InitBinder("foo")
        protected void initBinder(WebDataBinder binder) {
            binder.setValidator(new FooValidator());
        }
    
        @RequestMapping(value="fooPage", method = RequestMethod.POST)
        public String processSubmit(@Valid Foo foo, BindingResult result, ModelMap m) {
            if(result.hasErrors()) {
                return "fooPage";
            }
            ...
            return "successPage";
        }
    }
    

    【讨论】:

    • 如果我走这条路,我还能在Foo 中保留其他带有“正常”验证注释的字段,例如@NotNull@NotBlank 等吗?或者FooValidator 会覆盖所有这些吗? (显然我大大简化了事情,所以如果在其余的验证过程中充实我的例子会更有帮助,请告诉我。例如,我已经通过 Foo 类上的注释来处理其他 2 个自定义验证器存在多字段验证问题)
    • 我在 SO 上发现了另一个问题,可以很好地回答这个问题:stackoverflow.com/questions/8819676/…。基本上,您让控制器使用注释自动验证。然后,在控制器方法中调用您的自定义验证器,传递您之前验证的绑定结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 2014-04-29
    • 2011-07-03
    • 2020-06-25
    • 1970-01-01
    • 2011-11-20
    相关资源
    最近更新 更多