Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access Map<Enum, Object> in JSTL

Tags:

java

enums

jsp

jstl

I have:

public enum MyEnum{
    One, Two, Three
}

From controller, I put in the model:

HashMap<MyEnum, Long> map = new HashMap<MyEnum, Long>();
map.put(MyEnum.One, 1L);
mav.addObject( "map", map);

How do I in my JSTL access the object in the map for key enum MyEnum.One, in a neat way?

${map['One']} //does not seem to work...

nor does

${map[MyEnum.One]}
like image 237
Patrick Avatar asked Oct 11 '09 23:10

Patrick


2 Answers

It's not exactly true that you can't do it, but the solution isn't completely straight forward. The issue is EL is not converting the string you pass in as the map key to the corresponding enum for you, so putting ${map['One']} does not use the enum constant MyEnum.One in the map lookup.

I ran into the same issue and didn't want to revert to going with a String keyed map, so the challenge then was in JSTL how to get the actual enum reference to use in the map lookup.

What is required is to get the Enum constants into the scope of the JSP so that you can then use the actual Enum itself as the key. To do this, in the controller you do something like this:

for (MyEnum e : MyEnum.values()) {
  request.putAttribute(e.toString(), e);
}

What you've done here is added variables into the scope named as the string representation of the enum. (you could of course avoid naming issues by prepending the e.toSring() with some value)

Now, when you do the following

${map[ONE]}

You will be using the actual enum constant as the key and will therefore get back the proper corresponding value from the map. (notice there are no quotes around ONE, that is because you are referencing the request attribute ONE in this case, that was added above)

like image 174
binkdm Avatar answered Sep 22 '22 20:09

binkdm


You can't. Your best bet is to change your map to use enum.name() as key:

HashMap<String, Long> map = new HashMap<String, Long>();
map.put(MyEnum.One.name, 1L);
map.addObject( "map", map);

Your first approach would work then:

${map['One']} // works now

Or you can write a custom EL function to do the above for you if you can't / don't want to change the map.

like image 41
ChssPly76 Avatar answered Sep 19 '22 20:09

ChssPly76