Java EL评估bean的属性

时间:2014-02-20 13:34:56

标签: java jsp el

我有一个变量${path},其中包含一个字符串“a.b.c”我想将此作为对象$ {object}的属性进行评估:

如果我尝试${object[path]},则会抛出“未找到属性”

我会写成:

${object.a.b.c}

我可以拆分“。”并执行for循环object = object [split [i]]

但我发现它很难看。

我想要像:

eval("object."${path})

这可能吗?

1 个答案:

答案 0 :(得分:0)

您可以使用bean或函数作为中介来创建和评估 ValueExpression

package hoteval;

import javax.el.*;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.servlet.jsp.*;

@ApplicationScoped
@Named
public class Expr {
  public Object eval(PageContext pageContext, String expression) {
    ExpressionFactory factory = JspFactory.getDefaultFactory()
            .getJspApplicationContext(pageContext.getServletContext())
            .getExpressionFactory();
    ELContext elCtxt = pageContext.getELContext();
    ValueExpression ve = factory
                     .createValueExpression(elCtxt, expression, Object.class);
    return ve.getValue(elCtxt);
  }
}

调用语法如下所示:

${expr.eval(pageContext, "${bean.prop}")}

针对Glassfish 4.0编写/测试。


以上代码只是一个例子。要提供${expr.eval(pageContext, object, path)}表单的表达式,其中路径a.b.c,可以将其重写为:

  public Object eval(PageContext pageContext, Object o, String path) {
    expression = "${_tmpRootObject."+expression+"}";
    pageContext.setAttribute("_tmpRootObject", o);
    //etc.

评估代码同样可以成为采用ex:eval(...形式的函数。

关于使用ELResolver的评论。

  • 您可以在JspApplicationContext中的ServletContextListener(见上文)中添加 ElResolver
  • 它将在大多数其他解析器之前被调用 - see order
  • 但现在你在getValue(ELContext, Object, Object)遇到了一些问题。
    • 对于${object[path]},您可以获得 path 所解析的任何值,并且需要区分它与其他属性(bean属性/地图值/等)。
    • 只要您检查基本类型不是 Map ,查找包含.的字符串实例就足够了。
    • 您可能需要拆分字符串并使用反射来查找属性。
    • 我不认为支持嵌套评估(在 ELResolver 中解析 ValueExpression ),但我可能错了。