Spring MVC验证复选框列表

时间:2012-06-11 22:02:23

标签: validation spring-mvc checkbox constraints

我有以下豆子:

public class CodedEntity {
    private String name;
    private String code;
    // getters and setters
}

public class MyProduct {
    @javax.validation.constraints.Size(min = 1)
    private List<CodedEntity> codedEntities;
    // getters and setters
}

如您所见,codedEntities列表必须至少包含一个元素。

在我的控制器中,我会像这样验证列表的大小:

@RequestMapping(value = "/**", method = RequestMethod.POST)
public String submit(@Valid final MyProduct myProduct, final BindingResult result,
        final Model model) {
    // ...
}

最后我的jsp:

<c:forEach items="${codedEntitiesList}" var="codedEntity" varStatus="loopStatus"        
    <form:checkbox path="myProduct.codedEntities[${loopStatus.index}]" value="${codedEntity.code}" cssClass="checkbox" />
</c:forEach>

这里的问题如下:当我提交jsp而不检查任何复选框时,spring mvc返回一个包含“null”元素的非空列表。因此,验证失败。

如何告诉spring-mvc返回一个空列表而不是一个满是“null”元素的列表?或者至少我有什么方法可以验证我的约束?

2 个答案:

答案 0 :(得分:0)

使用一些Javascript可能更容易做到这一点,否则如果你想要一个纯java实现,我会实现自己的注释。像@ListContainsValue这样的东西应该不是那么难实现。如果您需要一个如何实现自己的验证注释的示例,那么这里有一个非常好的注释:

Cross field validation with Hibernate Validator (JSR 303)

答案 1 :(得分:0)

我终于找到了解决方案。我不知道它是否是最好的,但它肯定是一个很好的。

首先,必须像这样修改jsp:

<c:forEach items="${codedEntitiesList}" var="codedEntity" varStatus="loopStatus"        
    <form:checkbox path="myProduct.codedEntities" value="${codedEntity}" />
</c:forEach>

您必须创建自定义编辑器:

public class CodedEntityEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(final String text) {
        final CodedEntity codedEntity = new CodedEntity();
        codedEntity.setCode(text);
        this.setValue(codedEntity);
    }

    @Override
    public String getAsText() {
        return ((CodedEntity) this.getValue()).getCode();
    }
}

当然,不要忘记将CodedEntityEditor绑定到Controller:

@InitBinder
public void initBinder(final WebDataBinder binder) {
    binder.registerCustomEditor(CodedEntity.class, new CodedEntityEditor());
}

最后,您必须在CodedEntity对象中实现hashCode()和equals()方法。您必须执行此操作,因为CodedEntityEditor中的getAsText方法通过其引用检索对象。 如果您实现这两个方法,它将在特定字段(在我的情况下为“代码”字段)中检索它。为了方便起见,我建议使用像Eclipse这样的IDE来自动生成它们。 仅举例来说,这是Eclipse生成的2个方法:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((this.code == null) ? 0 : this.code.hashCode());
    return result;
}

@Override
public boolean equals(final Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (this.getClass() != obj.getClass())
        return false;
    final CodedEntity other = (CodedEntity) obj;
    if (this.code == null) {
        if (other.code != null)
            return false;
    } else if (!this.code.equals(other.code))
        return false;
    return true;
}

当然你可以跳过这两种方法,但在这种情况下,当你重新加载页面时,不会检查复选框!