Wednesday, October 23, 2002 07:15 PM
First, an answer to your second (yet more important) question: The JSTL Specification provides a complete (224 page) description of all the tags and how each is used.
Now, after reading the spec, you'll notice that the
forEach tag will loop over arrays,
java.lang.Strings (as a list of comma-separated values). Even though you are using
java.util.Hashtable, which implements
java.util.Map your code does not work... :(
So why not? In the case of a
java.util.Map, a set view of the mappings is obtained by calling
entrySet(). This results in a set of objects implementing
java.util.Map.Entry, each of which contains two properties ("key" and "value"--but no "user" property). Therefore, you would need some code within the loop to get from there to the user name. But I thought custom tags were supposed to minimize (or eliminate) scriptlet code... Read on. :)
Another option is to do exactly what your scriptlet is doing: get an
Enumeration view of the
HashTable values using the
elements() method. Then, use the
forEach tag with the
Enumeration. Ideally, the servlet or filter that is setting the
Hashtable as an attribute would instead set the resulting
Enumeration as the attribute "users". This would allow you to use the JSP using JSTL code you gave in your post without changes.
Or, if you want to get away from the old-fashioned (although not-yet deprecated)
Enumeration interface, you can use the
values() method to retrieve a
Collection view of the
Hashtable values and set it as your "users" attribute.
Or, if you're really motivated, you might want to move away from the "heavyweight"
Hashtable and move up the the Java 2 Collections API's
HashMap. Note that in doing so, you lose the synchronization code in the
Hashtable--but this is good because it allows you to synchronize only the critical code blocks (thereby improving performance).
I hope you don't mind the answers to the questions you didn't ask... :)