【问题标题】:Dynamic bean properties for EL by implenting java.util.Map#get通过实现 java.util.Map#get 实现 EL 的动态 bean 属性
【发布时间】:2014-04-28 20:40:00
【问题描述】:

我有一个@SessionScoped bean,我想将它用作映射,以便我可以在视图中使用 EL 动态获取它的属性。

myBean['someDynamicProperty']

我通过实现 java.util.Map、使用我的应用程序逻辑实现 get(Object o) 并在所有其他覆盖的 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 定义动态属性?

【问题讨论】:

    标签: java jsf el


    【解决方案1】:

    最好将映射存储为会话属性,这样您就不需要创建@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']}
    

    来自 cmets:

    问题是我的 bean 并不是真正的 Map。在 get 方法中,我根据收到的密钥实现所需的逻辑。 (...) 就我而言,getter 中的业务逻辑并不昂贵。

    似乎在某种程度上你需要你的 bean 来实现Map 接口。而是重新发明轮子或将方法标记为抛出UnsupportedOperationException,从已经实现所有方法的类扩展,如HashMapLinkedHashMap,或者实现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...
    }
    

    【讨论】:

    • 我通过使用 @Named 注释我的 bean 来实现这一点。然而,这并不能回答问题。问题是我的 bean 并不是真正的 Map。在 get 方法中,我根据收到的密钥实现所需的逻辑。
    • @maxmil 我可以推断您的 bean 是从 Map 或类似的东西扩展而来的。我提出这个解决方案是因为我假设你的 getter 没有任何业务逻辑。请注意getter methods being called multiple times
    • 多次调用 getter 方法是一个很好的考虑,尽管在我的例子中,getter 中的业务逻辑并不昂贵。
    • 你肯定想让你的代码写成extends AbstractMap
    • 如果我扩展 AbstractMap 我至少需要实现 entrySet()。我真的不想这样做,因为计算我的 bean 的所有属性可能会很昂贵。我真的只是想从一个根本不是 Map 的 bean 中获取 Map 在 EL 中给我的语法糖。我开始认为我使用 Map 界面不是一个好主意。
    猜你喜欢
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2010-10-26
    相关资源
    最近更新 更多