【问题标题】:Spring MVC validate a checkboxes listSpring MVC 验证复选框列表
【发布时间】:2012-06-11 22:02:22
【问题描述】:

我有以下豆子:

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”元素的列表?或者至少有什么方法可以验证我的约束?

【问题讨论】:

    标签: validation spring-mvc checkbox constraints


    【解决方案1】:

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

    Cross field validation with Hibernate Validator (JSR 303)

    【讨论】:

    • 有趣的链接,但我不明白创建新注释的意义,因为 javax.validation.constraints.Size 已经完成了这项工作。
    • 调试这个方法的时候,List的size字段是设置为复选框的个数,还是设置为0?
    • 不幸的是,它设置在复选框的数量上,这是我的问题。如果它是 0,那么我认为 @Size 注释会起作用。
    • 对,这让我觉得你需要实现一些自定义的东西,或者使用 javascript 来检查是否已检查。
    • 我不喜欢 javascript 验证,因为它会导致安全漏洞。
    【解决方案2】:

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

    首先,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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 2014-07-13
      • 1970-01-01
      • 2012-03-02
      • 1970-01-01
      • 2014-02-08
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多