I have a Bean ...">

Javax.servlet.ServletException: javax.servlet.jsp.JspTagException: I donโ€™t know how to iterate over supplied "elements" in <forEach>

I have a Bean that contains results. I need to use JSTL to iterate over and present the results. Here is the bean:

public class DetResults { private List<String> headings; private List<Class<?>> types; private List<Object[]> data; public DetResults() {} public List<String> getHeadings() { return this.headings; } public String getHeading(int which) { return this.headings.get(which); } public List<Class<?>> getTypes() { return this.types; } public Class<?> getType(int which) { return this.types.get(which); } public List<Object[]> getData( ) { return this.data; } public Object[] getDataAtRow( int row ) { return this.data.get(row); } public void setHeadings( List<String> val ) { this.headings = val; } public void setHeadings( String[] val ) { this.headings = Arrays.asList(val); } public void addHeading( String val ) { if( this.headings == null ) this.headings = new ArrayList<String>(); this.headings.add(val); } public void setTypes( List<Class<?>> val ) { this.types = val; } public void setTypes( Class<?> val[] ) { this.types = Arrays.asList(val); } public void addType( Class<?> val ) { if( this.types == null ) this.types = new ArrayList<Class<?>>(); this.types.add(val); } public void setData( List<Object[]> val ) { this.data = val; } // allow NPE to get thrown public void setDataAtRow( Object[] val, int row ) { this.data.set(row, val); } public void appendDataRow( Object[] val ) { if( data == null ) data = new ArrayList<Object[]>(); this.data.add(val); } public int getColumnCount() { return this.headings!=null?this.headings.size():0; } } 

Here is the handler that installs Bean in the JSP:

 DetResults results = detDAO.fetchDetResults(paramBean); request.setAttribute("results", results); action.setJspURI(".../.jsp"); 

I tried to display it as follows:

 <c:forEach var="results" items="${results}"> ${results.heading} </c:forEach> 

But this threw the following exception:

Raised: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: don't know how to iterate over the provided "elements" in <forEach>

If I register the results on my handler page as follows:

 System.out.println( "\n\nthere are " + results.getColumnCount() + " columns in the result set" ); for( int i=0; i<results.getColumnCount(); i++ ) { System.out.println( results.getHeading(i) + " --> " + results.getType(i) ); } 

Logs seem to display well on the server.

+7
source share
2 answers

Called: javax.servlet.ServletException: javax.servlet.jsp.JspTagException: I donโ€™t know how to iterate over the provided "elements" in <forEach>

This will happen when <c:forEach items> does not reference a valid object through which it can iterate. The object must be Object[] (simple array), Collection , Map , Iterator , Enumeration or String (see also source code ). Anything else that cannot be repeated with <c:forEach> . Your DetResults class DetResults not an instance of any of the above types, so it does not work.

Your DetResults class does not look right. It looks basically like one God bean with a set of all the properties of several separate objects. It is not right. The bean class must represent no more than one object. Rewrite your DetResults class so that you end up with a complete javabeans collection:

 List<DetResult> results = detDAO.fetchDetResults(paramBean); 

so that you can access it as follows:

 <c:forEach items="${results}" var="result"> ${result.heading} <c:forEach items="${result.data}" var="dataItem"> ${dataItem} </c:forEach> </c:forEach> 

If you really insist on keeping the DetResults bean as it is, you can access it as follows:

 <c:forEach begin="0" end="${results.columnCount}" varStatus="loop"> ${results.headings[loop.index]} <c:forEach items="${results.data[loop.index]}" var="dataItem"> ${dataItem} </c:forEach> </c:forEach> 

See also:


Unrelated to the specific problem, the <c:forEach var> attribute is invalid. You must not specify the same name as an existing object in the scope. It will only be a collision. But this is a topic for a new question if you cannot interpret the error message.

+24
source

You should be able to iterate over the headers.

 <tr> <c:foreach var="heading" items="${results.headings}"> <th>${heading}</th> </c:foreach> </tr> 

And then according to ...

 <c:foreach var="row" items="${results.data}"> <tr> <c:foreach var="i" items="${row}"> <td>${i}</td> </c:foreach> </tr> </c:foreach> 

Or something like that?

+1
source

All Articles