Fill a list from JSP in Spring
I have something like this in my Spring Application:
public class Book{
public Book(){
sheets = new LinkedList<Sheet>();
}
protected List<Sheet> sheets;
//getter and setter
}
I add several Sheets to the sheet list and I print a form in a JSP like this:
<form:form modelAttribute="book" action="${dest_url}" method="POST">
<c:forEach items="${mybook.sheets}" var="sheet" varStatus="status">
<form:hidden path="sheet[${status.count -1}].header"/>
<form:hidden path="sheet[${status.count -1}].footer"/>
<form:hidden path="sheet[${status.count -1}].operador"/>
<form:hidden path="sheet[${status.count -1}].number"/>
<form:hidden path="sheet[${status.count -1}].lines"/>
</c:forEach>
...
</form:form>
I need to get back this list in the controller when the form is submitted. So in my controller I have a method with a parameter like this:
public String myMethod (@ModelAttribute("book") Book book, Model model){
...
}
The problem is that it doesn't fill the sheets list unless in the constructor of Book I add as much Sheet's as I want to get. The problem is that I don't know in advance the number of Sheets the book is going to have.
I think the problem is that in my method it instantiates Book which has a list of sheets with 0 elements. When it tries to access to sheets[0] the list is empty and it doen't add a Sheet. I've tried to create a getter method for the list with an index parameter (so it can create the element if it doesn't exists in the list like in Struts framework) like this one:
public Sheet getSheets(int index){
if(sheets.size() <=开发者_如何学运维 index){
Sheet sheet = new Sheet();
sheets.add(index, sheet);
}
Sheet sheetToReturn = sheets.get(index);
if(sheetToReturn == null){
sheetToReturn = new Sheet();
sheets.add(index, sheetToReturn);
}
return sheetToReturn;
}
but with this method the JSP doesn't work because sheets has an invalid getter.
What's the proper way of filling a list when you don't know the number of items in advanced?
Thanks
If you make your list a lazy list (Apache Commons Collections LazyList or Spring's AutoPopulatingList) it will instantiate a new Sheet as a given list element at the moment you bind to it. Then you don't have to worry about how many items you've prepopulated the list with -- you can call list[17] on an empty list and it will be created on the fly and bound.
This getter is indeed not going to work. With collections in EL, ${bean.list[0]}
would roughly resolve to bean.getList().get(0)
, not to bean.getList(0)
as you seem to expect.
You need to pass the size of the list as a request parameter as well and prepare the list accordingly. You can use JSTL fn:length()
to get the size:
<input type="hidden" name="size" value="${fn:length(mybook.sheets)}">
(sorry, no Struts targeted example with form:hidden
, I don't use it, but it should give you an idea)
When the size is set, then you can prepare the list as follows:
for (int i = 0; i < this.size; i++) {
sheets.add(new Sheet());
}
That said, you can better use ${status.index}
instead of ${status.count - 1}
. See the LoopTagStatus
API for all available methods.
精彩评论