Passing form input values as a List of objects fro

2019-07-14 07:10发布

Here is a simplified (NOT real world) example. Suppose there is a domain model - a class Movie, which has a List of actors. A class Actor has three fields (name, birthDate, rolesNumber). The following code is an illustration of this scenario:

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
} 


There is also a JSP page where we output in a loop the information about every actor that plays in a concrete movie and the user can update the corresponding text field values and submit changes to a servlet:

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>
...


It is known that in order to retrieve text fields in a servlet, one can use ServletRequest's methods like getParameter() or getParameterValues() etc. But how to retrieve the updated input fields as a List of objects (so that every three related values were grouped)?

If it were Spring project we could use Spring's <form:form modelAttribute="modelName">
tag and have a backing object defined in the modelAttribute. But how about pure JSP/Servlet project?

Possible solution

One of the possible solutions is to assign names in the "name" attribute of the text inputs and append varStatus.index, like this:

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

So this index would allow us to identify values related to ONE object. And we could also generate some hidden input field where we could store a loop count (a number of actors), and then in a servlet we could retrieve the values related to one object like this:

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);
}

My questions are:

  1. Is there another, more elegant and effective way of passing the updated text field values to a servlet as a List of objects?

  2. Is there any solution similar or equivalent to that of the Spring's <form:form> tag in a world of pure JSP/JSTL/EL/Servlets?


UPDATE

Looks like nobody knows the answer to the above questions. The accepted answer is not exactly what I asked for (see my comments to it).

There seems to be no equivalent of Spring's <form:form modelAttribute> tag or something similar in the world of pure Servlets/JSP.

Well, full Java EE, or Spring Framework, Apache Struts or another powerful web application framework to the rescue!

2条回答
可以哭但决不认输i
2楼-- · 2019-07-14 08:00

you can use the same name(revisionNumber) for all the inputs and use

String[] revisionNumber = request.getParamaterValues("revisionNumber") to get an array.

查看更多
乱世女痞
3楼-- · 2019-07-14 08:03

If you are returning this to a jsp page, it is advisable that you display it in a list directly by returning the object actors to the list directly. set it in your code to the session from the class, session.setAttribute("actorsList", actors);

Then in your JSP page, the list would be like this. (actorsList is the object set, you name it a name like act, then you can set a first initial static field in the list in option, and the list will loop on the getProperty to get the property "name" from your object.

<ffi:list collection="actorsList" items="act">
  <option value="">(Select An Actor)</option>
  <ffi:getProperty name="act" property="name"/>
</ffi:list>
查看更多
登录 后发表回答