我有一个变量${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),但我可能错了
- 对于