【问题标题】:Make JSF access a Map<String, ?> values from an EL instead of a bean fields?让 JSF 从 EL 而不是 bean 字段访问 Map<String, ?> 值?
【发布时间】:2013-07-26 21:09:11
【问题描述】:

是否有任何适当的方法来覆盖 JSF 从表达式语言访问 bean 字段的方式?我们的想法是模仿这种行为以访问 Map&lt;String, ?&gt; 值,其中 bean 字段将是映射键。

换句话说,是否可以使用#{beanContainingNestedMap.keyOfSaidNestedMap},就像keyOfSaidNestedMapbeanContainingNestedMap 的一个字段一样?

如果没有,我还有什么其他解决方案?


示例:

Holder.java

public class Holder {

    private Map<String, Object> objects = new HashMap<String, Object>();

    public void add(String key, Object value) {
        objects.put(key, value);
    }

    public Object getObject(String key) {
        return objects.get(key);
    }

}

ExampleBean.java

public class ExampleBean {

    private Holder holder = new Holder();

    public ExampleBean() {
        holder.add("foo", 42);
        holder.add("bar", 'X');
    }

    public Holder getHolder() {
        return holder;
    }

}

example.xhtml

<c:out value="#{exampleBean.holder.foo}" /> <!-- should print "42" -->
<c:out value="#{exampleBean.holder.bar}" /> <!-- should print "X" -->

如果我能做类似的事情会很棒(一种伪代码,因为我不知道这种方法是否存在;)):

@Override // override JSF's (if any...)
public Object resolveEl(String el) {
    try {
        super.resolveEl(el);
    } catch (ElException e) {
        Object bean = e.getBean();
        String fieldName = e.getFieldName();
        if (bean instanceof Holder) {
            Holder holder = (Holder) bean;
            Object value = holder.getObject(fieldName);
            if (value == null) {
                throw e;
            } else {
                return value;
            }
        }
    }
}

【问题讨论】:

  • 这个问题不是关于 JSF 而是关于 EL。 StackOverflow EL wiki 中有一个地图访问部分。举两个例子:${someMap[dynamicKey]}${some['class'].simpleName}
  • @LuiggiMendoza 感谢您的提示,但首先要知道是否可以使用#{beanContainingAMap.keyOfTheSaidMap} 代替,就像keyOfTheSaidMap 是bean 的字段一样。跨度>
  • 如果您检查我评论中提供的链接,您会发现目前不可能。你必须使用#{exampleBean.holder[foo]}
  • @LuiggiMendoza 无论如何它在技术上必须是可行的,我错了吗?我会稍等片刻,看看其他可能的答案。但不要犹豫,添加你自己的,因为如果你有唯一正确的答案,我会欣然接受;)
  • 您的问题令人困惑。 EL 已经支持使用与 javabeans 完全相同的语法进行映射。

标签: java jsf map javabeans el


【解决方案1】:

你可以通过EL直接使用地图。

Holder.java

public class Holder {

    private Map<String, Object> objects = new HashMap<String, Object>();

    public void add(String key, Object value) {
        objects.put(key, value);
    }

    public Map<String, Object> getObjectsMap() {
        return objects;
    }

}

EL

#{exampleBean.holder.objectsMap[your-key]}

【讨论】:

  • [your-key] 可以是动态表达式吗?
  • [your-key] 可以是动态表达式吗?任何帮助
  • @AnkitKumar:这取决于你的逻辑,如果你想构造动态密钥你可以使用&lt;c:set var="key" value="#{your dynamic value}" /&gt;
【解决方案2】:

这个问题不是关于 JSF 而是关于 EL。如@BalusC 评论中所述,您可以直接将您已经想要/需要的符号与Map 对象一起使用。我为此准备了一个基本示例(注意:这只是一个示例,应该保持原样或改进,因为它使用了 scriptlet 和 we must avoid scriptlets usage,但它是为了快速进行肮脏的测试):

<%@page import="edu.home.model.entity.User"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <%
        //Scriptlets usage, sorry. This code must be moved to a Servlet or another controller component
        //defining the map
        Map<String, User> aMap = new HashMap<String, User>();
        //defining a value for the map
        User user = new User();
        user.setFirstName("Luiggi");
        user.setLastName("Mendoza");
        //adding the value in the map 
        aMap.put("userLM", user);
        //making the map accesible in EL through PageContext attribute
        pageContext.setAttribute("aMap", aMap);
    %>
    <!-- Accessing directly to the userLM key and its attributes -->
    ${aMap.userLM.firstName} - ${aMap.userLM.lastName}
</body>
</html>

用户类代码(为测试目的而最小化):

public class User {
    private String firstName;
    private String lastName;
    //empty constructor
    //getters and setters
}

这会生成一个打印的 JSP 页面:

Luiggi - Mendoza

请注意,这(除了 scriptlet 部分)也适用于 Facelets 页面,因为这是 EL 而不是 JSF。

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2023-03-30
    • 2023-03-05
    • 2011-01-10
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-27
    相关资源
    最近更新 更多