1

我有一个对象Foo,它包含对 object 的引用,Bar该引用具有对 object 的引用Baz,并且为了Foo有效,Bar必须对Baz.

问题是它Bar 不需要有效的、非 nullBaz的有效,所以我不能简单地将验证放在那里,我需要它在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;
}

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

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

4

1 回答 1

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";
    }
}
于 2012-04-05T19:46:47.973 回答