• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JSTL possibly not recognizing my class because it implents the Map interface

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I hope someone can shed some light on this. I'm very new to jsp/servlets/jstl/struts, java web development in general.

In one of my Struts Action classes, I was placing a java.util.Map into the request scope.

In the JSP doing the rendering for the action, I wanted to use the keySet of the map. Because .keySet() isn't actually a getter, I decided to make an inner wrapper class with the method .getKeySet(). I also wanted to be able use this same wrapper object as a normal Map. So I implemented the Map interface, delegated all the Map methods to my internal map, and created my .getKeySet() method which simply returned the keySet from the internal Map.

Pseudo-code (this was an inner class of the Action):


I had JSTL code in the JSP that looked like this:


It didn't work. I didn't error either, but it produced no output at all.
So I started debugging. Here's what I started with:


The first two lines in the last bit of code printed out:
com.my.package.some.CustomServlet$MapWrapper@3dc3943f
3

Which made sense. It got the classname in the toString, and the count was correct.
Strangely, the 3rd and 4th lines printed out nothing at and 0, respectively.

I thought this was odd and continued to attempt to debug for several hours. Eventually I commented out the Map interface on my MapWrapper class, and suddenly all of the debug lines started working!

So it appeared that JSTL couldn't access my custom methods if my wrapper class was implementing the Map interface.

I have since "solved" my problem and have basically worked around it, but I am really curious to understand why this behaved the way it did. Seems like this would really help further my understanding of JSTL because this would seem to be an odd problem. I didn't find anything on this site or Google.



Anyone have any insight?

Thanks!
 
Sheriff
Posts: 14691
16
Eclipse IDE VI Editor Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't know which version of JSTL you're using, but you seem to be years behind ;) Map is perfectly recognized in the forEach tag. The "var" attribute will be of type Map.Entry, so then you can use customer.key, customer.value

Looping through the keys :
 
Arjumand Bonhomme
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Slight correction, when I said the debugging statements started working after removing the Map interface from my wrapper class, I meant the 3rd and 4th statements. The 2nd statement, "fn:length(...)" obviously stopped working because the JSTL no longer interpreted the wrapper class itself as a collection.
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Arjumand Bonhomme:
I decided to make an inner wrapper class with the method .getKeySet()

Why do you not just iterate over the Map and extract the keys from the Map.Entry instances as Satou demonstrated? Why over-engineer the process?
[ February 28, 2007: Message edited by: Bear Bibeault ]
 
Arjumand Bonhomme
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for you observations, by the end of my debugging session, I realized how I "could"/"should" do it with the Map.Entry class.

However, this still doesn't explain the behavior I saw. I can do everything that I need to with the Map.Entry style, but what I'm seeking is greater understanding. Knowing how to make something work is great, but knowing why something works (or doesn't in this case) is much much more useful and fulfilling.

I don't simply want to get my project done, I want to understand as much as possible about all the technologies I'm using. So basically this isn't a help me get my project working thread, it's more of a help me have a better understanding thread

Hope one of you can help relay the "why" behind all this.

Thanks!

Cheers!
 
Bear Bibeault
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Arjumand Bonhomme:
but knowing why something works (or doesn't in this case) is much much more useful and fulfilling.



I'm 100% with you on that!

Problem is, the volunteers who answer questions here, myself included, don't always have the time to dig in as much as we'd like to.

That said, I've done something similar -- implement a Map to use with the JSTL -- many times without issue.
 
Arjumand Bonhomme
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Bear

Thanks! good to meet people who share the same sentiment.


That said, I've done something similar -- implement a Map to use with the JSTL -- many times without issue.



Have you ever added additional (ie non-Map) getters/setters to an object implementing Map and used those additional properties via JSTL?


I also understand what you mean about limited time. If this thread doesn't yield the answer, then I will simply have to put this on my list of things to come back and re-visit when my project is done (even though we know they are seldom ever "done").

Thanks again!
 
Christophe Verré
Sheriff
Posts: 14691
16
Eclipse IDE VI Editor Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I don't clearly understand where the problem is

The spec says :
6.1.2
If the items attribute is of type java.util.Map,
then the current item will be of type java.util.Map.Entry,

So if your request attribute is an instance of Map,
the "var" attribute will be a Map.Entry, not a MapWrapper.
No matter what you do, JSTL sees it as a Map instance, so it returns a list of Map.Entry, preventing you from calling your beloved custom methods.
The only way to do it is, as you said, to remove the implementation of a Map.

Hope one of you can help relay the "why" behind all this.


I hope it did
[ February 28, 2007: Message edited by: Satou kurinosuke ]
 
pie. tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic