Spring 3 MVC: ошибка привязки к полям формы списка при отправке - PullRequest
0 голосов
/ 08 сентября 2010

Позвольте мне представить мою проблему, предоставив часть кода.

Первый объект моей формы:

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 s

public class OrgChartFormElement {
    private boolean selected;
    private String elementLabel;
    private Long id;

    //default constructor, getters and setters
}

Я использую context:component-scan и mvc:annotation-driven, поэтому мой контроллер выглядит так:

@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:

Found model attribute: true
[]

Вот мой фрагмент JSP:

<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 рендерится, и я вижу свой список полей ввода текста с ожидаемыми значениями, что говорит мне, что я правильно использую теги spring-form. Однако, когда я отправляю, объект поддержки формы, объявленный как параметр (orgChartForm) в методе обработчика POST, инициализируется, но все инициализируется нулем / по умолчанию. Я не знаю, куда отправлены предоставленные данные! Кажется, что springMVC теряет его и просто создает новый объект.

Я широко использовал этот шаблон в этом приложении без сбоев. Это просто не будет работать здесь. Я понимаю, что в моем приложении это особый случай, когда поле формы не атомарное, а список, однако меня действительно смущает, что данные связываются в GET-запросе, но не в POST.

Заранее спасибо за любые указатели!

Ответы [ 2 ]

0 голосов
/ 29 октября 2013

Я думаю, вам нужно написать PropertyEditorSupport для вашего класса.Ниже приведен пример для справки.

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 следующим образом:

@InitBinder
protected void initBinder(HttpServletRequest request, WebDataBinder binder) {
    binder.registerCustomEditor(List.class, "list", new SampleEditor(this.sampleService, List.class));
}

Надеюсь, что это решиттвоя проблема.

0 голосов
/ 10 сентября 2010

Я думаю, что проблема в том, что вы пытаетесь связать произвольное количество полей формы с ArrayList, который представляет собой список с заранее определенным размером.

Spring имеет нечто, называемое AutoPopulationList, специально разработанное для этой цели. Пожалуйста, посмотрите на эту ссылку для получения дополнительной информации о том, как ее использовать: http://blog.richardadamdean.com/?p=12

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...