如何使用@Valid注释在Spring 3中验证复杂的模型对象?

时间:2011-05-25 16:31:05

标签: validation spring-mvc bean-validation

我有一个建模采购订单的模型对象。采购订单包含一些字段(例如ID和日期)以及作为ArrayList的行项列表。我可以验证父购买订单确定,但在验证订单项时会窒息。

任何人都可以帮我验证复杂的物体吗?如果我无法自动神奇地验证复杂对象,我如何编写依赖于父级中的约束注释的自定义验证器,然后迭代子行项目?此Validator实例需要能够调用something.validate(purchaseOrder)和(对于每个行项目)something.validate(lineItem)。我从哪里得到“东西”?

我在<mvc:annotation-driven />中指定了dispatcher-servlet。我没有使用@InitBinder。我在控制器的方法中使用@Valid注释进行验证,如

    @RequestMapping(params="confirmPurchaseOrder")
    public String confirm(
            @ModelAttribute("purchaseOrder") @Valid PurchaseOrder purchaseOrder,
            BindingResult result,
            @RequestParam("account") String accountString,
            @RequestParam("division") String divisionString,
            Model model)
    {
        if (result.hasErrors()) {
            return PURCHASE_ORDER_CREATE_VIEW;
        }

域类看起来像这样: -

public class PurchaseOrder implements Comparable<PurchaseOrder> {
    /** Based on GUID */
    private String id;

    /** SOP */
    @NotNull
    private Integer SOP;

    /** Reference from client */
    @NotBlank
    private String purchaseOrderReference;

    /** PO date */
    @DateTimeFormat(style="S-")
    @NotNull
    private Date date;

    @Valid
    private final Collection<LineItem> lineItems = new ArrayList<LineItem>();

public class LineItem {
    ...Elided

    /** Generated from GUID */
    private String id;

    @NotNull
    @DateTimeFormat(style="S-")
    @Future
    private Date expiry;

    private String softwareVersion;

    @NotNull
    @NumberFormat(style = Style.NUMBER)
    @Min(1)
    private Integer licenceCount;

当提交具有空的到期日期的采购订单时,我得到以下例外:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property 'lineItems[]' of bean class [com.nit.ols.domain.PurchaseOrder]: Invalid index in property path 'lineItems[]'; nested exception is java.lang.NumberFormatException: For input string: ""
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:730)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:634)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

2 个答案:

答案 0 :(得分:2)

PurchaseOrder课程中,尝试将lineItems集合更改为List。看起来您在this问题中解决了同样的问题。

答案 1 :(得分:1)

就像David说的那样,声明类型为lineItems的{​​{1}}应该可以解决问题。在Hibernate Validator 4.2.0 CR1(尚未发布的atm,如果您感兴趣,可以使用最新的快照构建)List也应该有效,请参阅HV-468了解更多详情。