I have a EnumMap:
EnumMap<Gender, Integer> genderMap = new EnumMap(Gende开发者_开发百科r.class);
where Gender is public enum Gender {Male, Female};
And I have req.setAttribute("genderMap", genderMap);
Now I want to get the value from genderMap
by a key in JSP file:
${genderMap['Male']}
but this doesn't get the value in genderMap
. Why?
Don't use enum mappings. Just use enums as enums in Java and as strings in JSP/EL.
I'll assume that you need that integer because of a database mapping. E.g. Male
is stored as 1
in database and Female
is stored as 0
in database. In that case, you need to redesign your enum as follows:
public enum Gender {
Male(1), Female(0);
private int id;
private Gender(int id) {
this.id = id;
}
public int getId() {
return id;
}
public static Gender valueOf(int id) {
for (Gender gender : values()) {
if (gender.id == id) {
return gender;
}
}
return null;
}
}
When populating the Person
from DB by JDBC, just do
person.setGender(Gender.valueOf(resultSet.getInt("gender")));
When showing preselected options to enduser in JSP, just do
request.setAttribute("genders", Gender.values());
and
Gender:<br/>
<c:forEach items="${genders}" var="gender">
<input type="radio" id="gender_${gender.id}" name="gender" value="${gender.id}"
${gender == person.gender ? 'checked="checked"' : ''} />
<label for="gender_${gender.id}">${gender}</label>
<br />
</c:forEach>
or even without the id
Gender:<br/>
<c:forEach items="${genders}" var="gender">
<input type="radio" id="gender_${gender}" name="gender" value="${gender}"
${gender == person.gender ? 'checked="checked"' : ''} />
<label for="gender_${gender}">${gender}</label>
<br />
</c:forEach>
When collecting submitted values in servlet, just do
Gender gender = Gender.valueOf(Integer.valueOf(request.getParameter("gender")));
or when using without id
in HTML
Gender gender = Gender.valueOf(request.getParameter("gender"));
Because 'Male'
evaluates to the String "Male", not to Gender.Male
. You would need to have access to the Gender.Male
constant to access its map entry. But accessing constants is not possible in JSP EL, so you might want to do :
req.setAttribute("male", Gender.Male);
req.setAttribute("genderMap", genderMap);
...
${genderMap[male]}
Map<Gender, Integer> genderMap = new HashMap<Gender, Integer>();
and
${genderMap['Male']}
this would work definitely.
My solution was to create a wrapper (adapter) for enum maps. It expects String keys and converts them to corresponding Enum values by calling Enum.valueOf() method.
Relevant parts from an example bean:
private Map <Action, Permission> permissions = new EnumMap<>(Action.class);
/** For java access */
public Map<Action, Permission> getPermissions() {
return permissions;
}
/** For EL access */
public Map<String, Permission> getPermissionsAsString() {
return new EnumMapWrapper<>(Action.class, permissions);
}
Now I can conveniently access the map elements in EL:
#{rule.permissionsAsString['MODIFY']}
Here's the wrapper class:
public class EnumMapWrapper<K extends String, V> implements Map<K, V> {
private Map<Enum, V> map;
private Class<? extends Enum> enumType;
public EnumMapWrapper(Class<? extends Enum> enumType, Map<? extends Enum, V> map) {
this.enumType = enumType;
this.map = (Map<Enum, V>)map;
}
private Enum valueOf(Object key) {
if (!(key instanceof String)) {
throw new IllegalArgumentException("Only string keys are permitted");
}
return Enum.valueOf(enumType, (String)key);
}
@Override
public int size() {
return map.size();
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public boolean containsKey(Object key) {
return map.containsKey(valueOf(key));
}
@Override
public boolean containsValue(Object value) {
return map.containsValue(value);
}
@Override
public V get(Object key) {
return map.get(valueOf(key));
}
@Override
public V put(K key, V value) {
return map.put(valueOf(key), value);
}
@Override
public V remove(Object key) {
return map.remove(valueOf(key));
}
@Override
public void putAll(Map<? extends K, ? extends V> m) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
map.clear();
}
@Override
public Set<K> keySet() {
throw new UnsupportedOperationException();
}
@Override
public Collection<V> values() {
return map.values();
}
@Override
public Set<Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
}
精彩评论