Передача входных значений формы в виде списка объектов со страницы JSP в сервлет
Вот упрощенный (НЕ реальный мир) пример. Предположим, есть модель предметной области - класс Movie, в котором есть список актеров. Класс Actor имеет три поля (name, birthDate, roleNumber). Следующий код является иллюстрацией этого сценария:
Movie.java
public class Movie {
// some fields
private List<Actor> actors;
// getters and setters
}
Actor.java
public class Actor {
private String name;
private Date birthDate;
private int rolesNumber;
// getters and setters
}
Существует также страница JSP, где мы выводим в цикле информацию о каждом актере, который играет в конкретном фильме, и пользователь может обновить соответствующие значения текстового поля и отправить изменения в сервлет:
actorsUpdate.jsp
...
<c:forEach items="${movie.actors}" var="actor">
<table>
<tr>
<th>Name</th>
<td><input type="text" value="${actor.name}" /></td>
</tr>
<tr>
<th>Birth Date</th>
<td><input type="text" value="${actor.birthDate}" /></td>
</tr>
<tr>
<th>Number of Previous Roles</th>
<td><input type="text" value="${actor.rolesNumber}" /></td>
</tr>
</table>
<hr />
</c:forEach>
...
Известно, что для извлечения текстовых полей в сервлете можно использовать такие методы ServletRequest, какgetParameter()
или же getParameterValues()
и т. д. Но как извлечь обновленные поля ввода в виде списка объектов (чтобы все три связанных значения были сгруппированы)?
Если бы это был проект Spring, мы могли бы использовать Spring<form:form modelAttribute="modelName">
тег и иметь вспомогательныйобъект, определенный в атрибуте modelAttribute. Но как насчет чистого проекта JSP/Servlet?
Возможное решение
Одним из возможных решений является назначение имен в атрибуте "name" текстовых входов и добавление varStatus.index, например:
<c:forEach items="${movie.actors}" var="actor" varStatus="counter">
<table>
<tr>
<th>Name</th>
<td><input type="text" name="name${counter.index}" value="${actor.name}" /></td>
</tr>
...
</table>
<hr />
</c:forEach>
Таким образом, этот индекс позволит нам идентифицировать значения, связанные с ОДНЫМ объектом. И мы могли бы также создать некоторое скрытое поле ввода, где мы могли бы хранить счетчик циклов (количество акторов), а затем в сервлете мы могли бы получить значения, относящиеся к одному объекту, например:
List<Actor> actors= new ArrayList<Actor>();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
for (int i = 0; i < count; i++) {
String name= request.getParamater("name" + i);
Date birthDate = dateFormat.parse(request.getParamater("birthDate" + i));
int rolesNumber = Integer.parseInt(request.getParamater("rolesNumber" + i));
Actor actor = new Actor(name, birthDate, rolesNumber);
actors.add(actor);
}
Мои вопросы:
Есть ли другой, более элегантный и эффективный способ передачи обновленных значений текстового поля сервлету в виде списка объектов?
Есть ли какое-либо решение, подобное или эквивалентное решению Spring?
<form:form>
тег в мире чистого JSP/JSTL/EL/Servlets?
ОБНОВИТЬ
Похоже, никто не знает ответа на поставленные выше вопросы. Принятый ответ не совсем то, что я просил (см. Мои комментарии к нему).
Кажется, нет эквивалента весны <form:form modelAttribute>
тег или нечто подобное в мире чистых сервлетов /JSP.
Ну что ж, полная помощь Java EE, Spring Framework, Apache Struts или другой мощной среды веб-приложений!
2 ответа
Вы можете использовать одно и то же имя (revisionNumber) для всех входов и использовать
String[] revisionNumber = request.getParamaterValues("revisionNumber")
получить массив.
Если вы возвращаете это на страницу jsp, желательно, чтобы вы отображали его в списке напрямую, возвращая объектные субъекты непосредственно в список. установите его в своем коде для сеанса из класса, session.setAttribute("ctorsList", актеры);
Тогда на вашей странице JSP список будет таким. (ctorsList - это набор объектов, вы называете его именем как act, затем вы можете установить первое начальное статическое поле в списке в параметре, и список будет зацикливаться на getProperty, чтобы получить свойство "name" из вашего объекта.
<ffi:list collection="actorsList" items="act">
<option value="">(Select An Actor)</option>
<ffi:getProperty name="act" property="name"/>
</ffi:list>