开发者

How to get the value in an EnumMap using a key in EL expression?

开发者 https://www.devze.com 2023-03-25 02:19 出处:网络
I have a EnumMap: EnumMap<Gender, Integer> genderMap = new EnumMap(Gende开发者_开发百科r.class);

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();
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号