Java EL评估bean上的属性



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

如果我尝试${object[path]},它会抛出一个"未找到属性">

我会被写成:

${object.a.b.c}

我可以在"."上进行拆分,并进行for循环object=object[split[I]]

但我觉得很难看。

我想要这样的东西:

eval("object."${path})

这可能吗?

您可以使用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的评论。

  • 您可以在Servlet上下文侦听器中向JspApplicationContext(见上文)添加一个ElResolver
  • 它将在大多数其他解析器之前被调用-请参阅顺序
  • 但是现在您在getValue(ELContext,Object,Object)中遇到了一些问题。
    • 对于${object[path]},您可以获得路径解析到的任何值,并且需要区分它和其他属性(bean属性/映射值等)
    • 只要检查基类型不是Map,就可以查找包含.的字符串实例
    • 您可能需要拆分字符串并使用反射来查找属性
    • 我认为不支持嵌套求值(在ELResolver中解析ValueExpression),但我可能错了

最新更新