Как я могу проверить сложный объект модели в Spring 3 с помощью аннотаций @Valid? - PullRequest
2 голосов
/ 25 мая 2011

У меня есть модельный объект, моделирующий заказ на покупку.В заказе на покупку есть несколько полей (таких как идентификатор и дата) и список позиций, например 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 ]

2 голосов
/ 26 мая 2011

В вашем классе PurchaseOrder попробуйте изменить коллекцию lineItems на List. Похоже, что у вас та же проблема, что и в этом вопросе.

1 голос
/ 28 мая 2011

Как сказал Дэвид, объявление lineItems типа List должно сработать.В Hibernate Validator 4.2.0 CR1 (еще не выпущен atm, вы можете использовать последнюю сборку моментальных снимков, если вам интересно), также Collection должно работать, см. HV-468 для получения дополнительной информации.

...