我有一个@SessionScoped bean,我想把它用作映射,这样我就可以在视图中使用EL动态获取它的属性。
myBean['someDynamicProperty']
我通过实现java.util.Map、用我的应用程序逻辑实现get(Object o)以及在所有其他overriden Map方法中抛出UnsupportedOperationException来实现这一点。
@SessionScoped
@Named
public class MyBean implements Map<String, String> {
@Override
public String get(Object key) {
// Application logic here
}
@Override
public boolean containsKey(Object key) {
throw new UnsupportedOperationException();
}
// All other map methods overriden like containsKey
}
属性是只读的,我只需要使用代码中的get方法,但不实现其他Map方法安全吗?
有没有更好的方法来定义bean中EL的动态属性?
最好将映射存储为会话属性,这样就不需要创建@SessionScoped
bean,并且可以通过表达式语言访问它,而不会出现问题。
public void methodThatShouldCreateTheMap() {
//declaring the variable as myBean for compatibility with your current code
Map<String, Object> myBean = new HashMap<String, Object>();
//fill myBean here...
//...
//store myBean in session
FacesContext.getCurrentInstance()
.getExternalContext()
.getSession(false)
.setAttribute("myBean", myBean);
}
您可以直接在EL:中访问地图
${myBean['key']}
来自评论:
问题是我的bean并不是真正的
Map
。在get方法中,我根据收到的密钥来实现所需的逻辑。(…)在我的情况下,getter中的业务逻辑并不昂贵。
在某种程度上,您似乎需要您的bean来实现Map
接口。相反,重新发明轮子或标记方法以抛出UnsupportedOperationException
,从一个已经实现所有方法的类(如HashMap
或LinkedHashMap
)扩展,或者从一个实现Map
但根本不实现的类(例如AbstractMap
)扩展,并保留其他方法为空:
@Named
@SessionScoped
public class MyBean extends AbstractMap<String, Object> {
@Override
public Object get(String key) {
//add your logic here...
}
@Override
public void set(String key, Object value) {
//do nothing...
}
//similar for other unnecessary methods...
}