JSTL c:forEach ServletException

I've been trying out the <c:forEach> tag having encountered it on p438/439 of HFS, but when I try to iterate over a map of arrays I get the following error from Tomcat:

javax.servlet.ServletException: Don't know how to iterate over supplied "items" in <forEach>

Here are the test page, JSP and servlet I created to test different collections. Request page test.html:

Here's TestJSTL.jsp:

Servlet code JstlTest.java:

and here's my servlet mapping for good measure:

I tried both a Map of simple arrays and ArrayLists to see if it makes a difference but it neither work. Using just a Map with no other collections in it is not a problem. It's only when the map has other collections in it that it fails with:

javax.servlet.ServletException: Don't know how to iterate over supplied "items" in <forEach>

Anyone else come across this or have I done something wrong? Should this happen? [ October 04, 2004: Message edited by: Roger Yates ]

Cheers,<br />Roger<br />SCJP 1.2, 1.4, SCBCD 1.3, SCWCD 1.4

Kathy Sierra

Cowgirl and Author
Rancher

Posts: 1589

5

posted 13 years ago

Howdy Roger, Things are a tiny bit different when you do a Map -- because remember, a map entry has two things--a key and a value, so when you iterate over it, you have to specify *which* you want--the key or the value. You want the value, which in turn is another list or array. I don't have time just now to check out your code in detail, but this should help you fix it:

In the place where you are iterating over the values of the Map (outer), you need to access (using the dot/property operator in EL) the "value" property of the Map like this:

<c:forEach var="inner" items="${outer.value}" >

That should fix it. Now, this means that for each entry in the Map named "outer", the VALUE of that entry will be assigned to the variable "inner".

The way you have it now, you're telling it to "iterate over the map, but I'm not going to tell you if I want you to iterate over the KEY or the VALUE for each of the entries in the Map..."

What you are probably thinking (which I originally wondered about too), was that it might just default to iterating over the values of the Map, but it doesn't. You have to tell is using the "value" property. If you want to iterate over the keys, you'd say "outer.key", I think (don't have the docs right here).

Anyway, this is not in the book, obviously And it isn't in the exam! But it's a great thing to know how to do, so I reckon it's good that you tried this.

Let us know if it works! -Kathy

Roger Yates

Ranch Hand

Posts: 118

posted 13 years ago

Once again - thanks Kathy!

I tried iterating using ${outer.value} as you suggested and successfully iterate over the values of the map (the arraylists or array). Interestingly when iterating over the map of arrays the output is: d e f a b c but when iterating over the map of ArrayLists, there's no new line: a b c d e f :roll:

Iterating over the keys also works, but is less interesting, so I won't put the output here!

In earlier tests I iterated successfully over a simple map (no collections inside it) without using .value or .key and it output something along the lines of "1=a", "2=b", "3=c" - i.e. it displayed both key and value.

Yes, as you say, I also thought it might default to iterating over .values - this would mean you didn't need to know the type of collection when writing your .jsp page. To quote a famous author: "They didn't ask us!"

Right, now for the next page...

Cheers,<br />Roger<br />SCJP 1.2, 1.4, SCBCD 1.3, SCWCD 1.4

Kathy Sierra

Cowgirl and Author
Rancher

Posts: 1589

5

posted 13 years ago

Originally posted by Roger Yates: Yes, as you say, I also thought it might default to iterating over .values - this would mean you didn't need to know the type of collection when writing your .jsp page.