从弹簧形式复选框元素接收EnumSet?

时间:2013-10-02 10:13:58

标签: java forms spring-mvc enums enumset

我在这个主题上看到了一些相关的问题,但没有一个看起来与我追求的完全一致。

我有一个表单,我希望用户能够从复选框列表中选择一些项目(由枚举支持),并将其作为Set接收。我有以下(以天为例)

我的枚举:

public enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}

将枚举值发送到控制器中的页面以显示为选项:

model.addAttribute("allDays", Day.values());

将选项编写为复选框并映射到正确的表单字段:

<form:form method="get" modelAttribute="filterForm" commandName="filterForm">
    <c:forEach items="${allDays}" var="item">
        <form:checkbox path="days" value="${item.name()}" label="${item.name()}"/>
    </c:forEach>
</form:form>

支持表单的表单对象:

public class FilterForm {

    private EnumSet<Day> days;

    public EnumSet<Day> getDays() {
        return days;
    }

    public void setDays(EnumSet<Day> days) {
        this.days = days;
    }
}

这可以正确显示选项,但是当我尝试提交时,我收到错误:

  

org.springframework.validation.BindException:   org.springframework.validation.BeanPropertyBindingResult:1个错误   字段'days'中对象'filterForm'中的字段错误:被拒绝的值   [0,1];代码   [typeMismatch.filterForm.days,typeMismatch.days,typeMismatch.java.util.EnumSet,typeMismatch];   参数   [org.springframework.context.support.DefaultMessageSourceResolvable:   代码[filterForm.days,days];参数[];默认消息[天]];   默认消息[无法转换类型的属性值   'java.lang.String []'到属性的必需类型'java.util.EnumSet'   '天';嵌套异常是   org.springframework.core.convert.ConversionFailedException:失败   从类型java.lang.String []转换为type   值为'{0,1}'的java.util.EnumSet;   嵌套异常是java.lang.IllegalArgumentException:不能   实例化集合类型:java.util.EnumSet]     org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:111)     org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:75)     org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:156)     org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:117)     org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)     org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)     org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)     org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)     org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)     org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)     org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)     javax.servlet.http.HttpServlet.service(HttpServlet.java:621)     javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

知道问题是什么,或者是否有更好的方法来实现这一目标? 感谢

2 个答案:

答案 0 :(得分:2)

我设法通过将表单更改为使用Set而不是EnumSet来解决此问题,并且我还修改了标记,以便提交的值保持选中状态:

<form:form method="get" modelAttribute="filterForm" commandName="filterForm">
    <form:checkboxes items="${allDays}" path="days" />
</form:form>

表格:

public class FilterForm {

    private Set<Day> days;

    public Set<Day> getDays() {
        return days;
    }

    public void setDays(Set<Day> days) {
        this.days = days;
    }
}

答案 1 :(得分:0)

您只需使用接口而不是实现。

您仍然可以使用EnumSet,但声明需要使用接口(无论如何这都是一种很好的做法)。

换句话说,请使用Abby's answer提供的代码。然后,您可以执行以下操作:

filterForm.setDays(EnumSet.allOf(Day.class));