【问题标题】:Evaluating EL expressions in request attributes评估请求属性中的 EL 表达式
【发布时间】:2012-12-27 04:37:25
【问题描述】:

我们将 HTML 标记存储在 XML 文档中,并使用 JiBX 进行解组。我们也使用 Spring,当这些对象之一添加到模型中时,我们可以通过 EL 在 JSP 中访问它。

${model.bookshelf.columnList[0].linkList[0].htmlMarkup}

没有什么开创性的。但是如果我们想在 HTML 标记中存储 EL 表达式呢?比如我们要存储下面的链接怎么办?

<a href="/${localePath}/important">Locale-specific link</a>

...并将其显示在一个 JSP 中,其中 LocalePath 是一个请求属性。

或者更有趣的是,如果我们要存储以下内容怎么办?

The link ${link.href} is in column ${column.name}.

...并在嵌套的 JSP forEach 中显示它...

<c:forEach var="column" items="${bookshelf.columnList}">
    <c:forEach var="link" items="${column.linkList}">
        ${link.htmlMarkup}
    </c:forEach>
</c:forEach>

请求属性中的这些 EL 表达式永远不会被计算。有没有办法让他们评估?类似“eval”标签的东西?令牌替换在第一个示例中有效,但在第二个示例中无效,并且不是很健壮。

【问题讨论】:

  • 您能否添加更多关于应用程序收到 HTTP 请求时执行的代码序列的详细信息?我问这个是因为我不太了解问题的背景。正如您所展示的,EL 表达式应该在以下情况下进行评估:(1) 您的应用程序已经执行了一些代码,这些代码将这些属性置于 JSP 范围之一中 (2) 您的标记稍后在请求过程中由 JSP 提供服务。跨度>

标签: jsp el jsp-tags taglib


【解决方案1】:

如果我理解正确:您正在寻找一种在运行时评估 EL 表达式的方法,该表达式存储在 EL 表达式提供的另一个值中 - 类似于递归 EL 评估。

由于我找不到任何现有的标签,我很快为这样的 EvalTag 整理了一个概念验证:

import javax.el.ELContext;
import javax.el.ValueExpression;
import javax.servlet.ServletContext;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class SimpleEvalTag extends SimpleTagSupport {
    private Object value;

    @Override
    public void doTag() throws JspException {
        try {
            ServletContext servletContext = ((PageContext)this.getJspContext()).getServletContext();
            JspApplicationContext jspAppContext = JspFactory.getDefaultFactory().getJspApplicationContext(servletContext);
            String expressionStr = String.valueOf(this.value);
            ELContext elContext = this.getJspContext().getELContext();
            ValueExpression valueExpression = jspAppContext.getExpressionFactory().createValueExpression(elContext, expressionStr, Object.class);
            Object evaluatedValue =  valueExpression.getValue(elContext);
            JspWriter out = getJspContext().getOut();
            out.print(evaluatedValue);
            out.flush();
        } catch (Exception ex) {
            throw new JspException("Error in SimpleEvalTag tag", ex);
        }
    }

    public void setValue(Object value) {
        this.value = value;
    }
}

相关顶级域名:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>custom</short-name>
  <uri>/WEB-INF/tlds/custom</uri>
  <tag>
    <name>SimpleEval</name>
    <tag-class>SimpleEvalTag</tag-class>
    <body-content>empty</body-content>
    <attribute>
      <name>value</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <type>java.lang.Object</type>
    </attribute>
  </tag>
</taglib>

用法:

<custom:SimpleEval value="${someELexpression}" />

注意:

我已经使用 Tomcat 7.0.x / JSP 2.1 对其进行了测试,但是正如您在源代码中看到的那样,没有特殊的错误处理等,因为它只是一些概念验证。

在我的测试中,它适用于使用${sessionScope.attrName.prop1} 的会话变量,也适用于使用${param.urlPar1} 的请求参数,但由于它使用当前JSP 的表达式评估器,我想它也适用于所有其他“正常”EL 表达式。

【讨论】:

  • 我使用的是 Tomcat 6.0.X/JSP 2.1,而且效果很好。谢谢!这似乎非常有用......我很惊讶这样的东西不是任何标准标签库的一部分。
  • 谢谢。我也很惊讶,但也许是因为将该功能添加到任何自定义标签(甚至是“独立”标签)并不是很复杂。
【解决方案2】:

您不需要自己以编程方式解析 el 表达式,应通过在 taglib 中包含 &lt;rtexprvalue&gt;true&lt;/rtexprvalue&gt; 来为您的标签提供评估结果,例如

   <tag>   
      <name>mytag</name>

      <attribute>
        <name>myattribute</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
       </attribute>
   </tag>

【讨论】:

    猜你喜欢
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多