首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring 3 MVC:在提交时发布对列表表单字段的绑定

Spring 3 MVC:在提交时发布对列表表单字段的绑定
EN

Stack Overflow用户
提问于 2010-09-08 15:46:11
回答 2查看 13.1K关注 0票数 0

让我通过提供一些有问题的代码来介绍我的问题。

首先是我的表单对象:

代码语言:javascript
复制
public class OrgChartForm {

    List<OrgChartFormElement> orgChartFormElements;

    public OrgChartForm() { 
        orgChartFormElements = new ArrayList<OrgChartFormElement>();
    }

    private OrgChartFormElement createOrgChartFormElementFromMprsStructureYear(MprsStructureYear structureYear){
        OrgChartFormElement element = new OrgChartFormElement();
        element.set.... // populate element based on attribute values from structureYear param
        return element;
    }

    public void createOrgChartFormElements(List<MprsStructureYear> structureYears) {
        orgChartFormElements = new ArrayList<OrgChartFormElement>();
        for(MprsStructureYear structureYear:structureYears){
            orgChartFormElements.add(createOrgChartFormElementFromMprsStructureYear(structureYear));
        }
    }

    // expected getters and setters
}

该表单包含一个简单的OrgChartFormElement列表

代码语言:javascript
复制
public class OrgChartFormElement {
    private boolean selected;
    private String elementLabel;
    private Long id;

    //default constructor, getters and setters
}

我使用的是context:component-scanmvc:annotation-driven,所以我的控制器看起来像这样:

代码语言:javascript
复制
@Controller
public class OrganisationStatusController{

    @Autowired(required=true)
    // dependencies here 

    @RequestMapping(value="/finyear/{finyearId}/organisationstatus", method=RequestMethod.GET)
    public String createRootOrg(@PathVariable(value="finyearId") Long finyearId, Model model) throws Exception {
        List<MprsStructureYear> orgStructuure = getOrganisationService().getOrganisationStructureForFinyear(finyearId);

        OrgChartForm orgChartForm = new OrgChartForm();
        orgChartForm.createOrgChartFormElements(orgStructuure);
        model.addAttribute("orgChartForm", orgChartForm);

        return "finyear/organisationchart/view";
    }

    @RequestMapping(value="/finyear/{finyearId}/organisationstatus", method=RequestMethod.POST)
    public String createRootOrg(@PathVariable(value="finyearId") Long finyearId,@ModelAttribute("orgChartForm") OrgChartForm orgChartForm, BindingResult result, Model model) throws Exception {
        System.out.println("Found model attribute: " + model.containsAttribute("orgChartForm"));
        List<OrgChartFormElement> elements = orgChartForm.getOrgChartFormElements();
        System.out.println(elements);
        return "redirect:/spring/finyear/" + finyearId + "/organisationstatus";
    }

    // expected getters and setters
}

问题出在POST处理程序。

目前,我从两个sysout语句中看到的输出是:

代码语言:javascript
复制
Found model attribute: true
[]

下面是我的JSP代码片段:

代码语言:javascript
复制
<sf:form modelAttribute="orgChartForm" method="post">
    <c:forEach items="${orgChartForm.orgChartFormElements}" var="org" varStatus="status">
        <sf:hidden id="${org.id}field" path="orgChartFormElements[${status.index}].id"/>
        <sf:input id="${org.id}hidden" path="orgChartFormElements[${status.index}].selected"/>
        <c:out value="${org.elementLabel}"/>(<c:out value="${org.id}"/>) - <c:out value="${status.index}"/>
    </c:forEach>
    <input type="submit" value="Submit" />
</sf:form>

当我发出GET请求时,JSP会呈现,并且我会看到文本输入字段的列表,其中包含期望值,这告诉我im正确地使用了spring-form标记。然而,当我提交时,在POST处理程序方法中声明为参数(orgChartForm)的表单支持对象被初始化,但一切都是空的/缺省初始化的。我不知道提交的数据到哪里去了!似乎springMVC失去了它,只是简单地构造了一个新对象。

我在这个应用程序中广泛地使用了这个模式,没有出现任何问题。在这里是行不通的。我意识到这是我的应用程序中的一个特例,其中表单字段不是原子的,而是一个列表,然而,数据绑定在GET请求中,而不是绑定在POST请求中,这真的让我感到困惑。

提前感谢您的指点!

EN

回答 2

Stack Overflow用户

发布于 2010-09-10 14:17:03

我认为问题在于,您试图将任意数量的表单域绑定到一个ArrayList,这是一个具有预定大小的列表。

Spring有一个称为AutoPopulatingList的东西,它是专门为此目的而定制的。有关如何使用它的更多信息,请查看此链接:http://blog.richardadamdean.com/?p=12

票数 0
EN

Stack Overflow用户

发布于 2013-10-29 13:17:55

我认为你需要为你的类编写PropertyEditorSupport。以下是示例,供您参考。

代码语言:javascript
复制
public class SampleEditor extends PropertyEditorSupport {

private final SampleService sampleService;

public SampleEditor(SampleService sampleService, Class collectionType) {
    super(collectionType);
    this.sampleService = sampleService;
}

@Override
public void setAsText(String text) throws IllegalArgumentException {
    Object obj = getValue();
    List list = (List) obj;
    for (String str : text.split(",")) {
        list.add(sampleService.get(Long.valueOf(str)));
    }
}

@Override
public String getAsText() {
    return super.getAsText();
}

}

在控制器中,您应该使用@InitBinder绑定它,如下所示:

代码语言:javascript
复制
@InitBinder
protected void initBinder(HttpServletRequest request, WebDataBinder binder) {
    binder.registerCustomEditor(List.class, "list", new SampleEditor(this.sampleService, List.class));
}

希望这能解决你的问题。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3665593

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档