Я искал этот ответ здесь и в Google без каких-либо успехов. Я объясню, что я ищу, и давайте посмотрим, сможет ли кто-нибудь помочь мне.
Используя Spring MCV, я передаю список объектов AList в свой view.JSP.
@RequestMapping(method = RequestMethod.GET)
public final ModelAndView getAList(){
ModelAndView mav = new ModelAndView("view");
List<A> aList = new ArrayList<>();
aList.add(new A("a1");
aList.add(new A("a2");
mav.addObject("aList", aList);
return mav;
}
Где выглядит A
public class A{
@Getter
@Setter
private String value;
public A(String value){
this.value=value;
}
}
Для каждой итерации списка я создаю форму. Форма выглядит
<c:forEach var="a" items="${aList}"
varStatus="status">
<form:form id="A${a.id}"
method="post" action="save.do"
modelAttribute="a">
<input type="submit" value="Save"/>
</form:form>
</c:forEach>
поэтому после завершения рендеринга у меня так много форм, как объекты в моем списке. Каждая форма, как вы можете себе представить, имеет свою кнопку отправки. Теперь то, что я пытаюсь сделать без успеха, - отправить одну из этих форм моему контроллеру, но не весь список A, который я визуализую, но A. Поэтому мой контроллер будет выглядеть примерно так.
RequestMapping(value = "/save", method = RequestMethod.POST)
public final ModelAndView save(@ModelAttribute("a") A a) {
Но я получаю "IllegalStateException: ни BindingResult, ни обычный целевой объект для bean-имени", потому что имя рендеринга myListAndView "aList" не совпадает с "a".
Я думаю, что я понимаю, что компоненты Spring MVC, такие как форма, не позволяют представить другой класс, который использовался в рендеринге. Даже если это вложенный класс класса рендеринга, что слишком плохо.
Я бы хотел, чтобы вам больше не приходилось отправлять aList.
Есть идеи?
С уважением.
Хорошо, это работает. Проблема в том, что элементы <form:xxx>
(например, <form:input>
) имеют проблему с путём, который начинается с элемента, который не находится в модели в части рендеринга.
Поэтому я немного изменил приведенный пример. Вот часть формы:
<ul><c:forEach var="a" items="${aList}" varStatus="status">
<li><form:form modelAttribute="a" action="save.do" method="POST" >
<input type="hidden" name ="index" value="${status.index}">
<input type="text" name ="value" value="${a.value}">
<input type="submit" value="Save"/>
</form:form></li>
</c:forEach></ul>
<li>
предназначены только для минимального форматирования, но важной частью является использование прямых элементов <input>
так что Spring MVC не задыхается от того, a
не является частью модели. Таким образом, рендеринг работает.
Теперь для части сохранения:
RequestMapping(value = "/save", method = RequestMethod.POST)
public final String save(@ModelAttribute("a") A a, @RequestParam("index") int index){
A aa = aService.getaList().get(index);
aa.setValue(a.getvalue());
return "redirect:/list";
}
Нет проблем, потому что имя атрибута model отсутствует в запросе POST. Springs просто создает новый A
и устанавливает его атрибут value. Это решение является расширяемым для сложных классов A. Единственная проблема заключается в том, что я не управляю ошибками, возвращаемыми Spring. Они должны управляться на глобальном уровне. (Я предположил, что URL-адрес для части списка был /list
)
Вместо того, чтобы пытаться отправить все содержимое выбранного элемента, рассмотрите возможность отправки идентификатора для выбранного элемента. Например:
<form:form method="post" action="save.do">
<c:forEach items="${aList}"
var="element"
varStatus="status">
<input type="submit"
name="selectedElementId"
value="${element.id}"/>
</c:forEach>
</form:form>