Jsp 计算请求属性中的EL表达式

Jsp 计算请求属性中的EL表达式,jsp,el,jsp-tags,taglib,Jsp,El,Jsp Tags,Taglib,我们将HTML标记存储在XML文档中,并使用JiBX解组。我们还使用Spring,当这些对象之一被添加到模型中时,我们可以通过EL在JSP中访问它 ${model.bookshelf.columnList[0].linkList[0].htmlMarkup} 没有什么突破性的。但是如果我们想在HTML标记中存储EL表达式呢?例如,如果要存储以下链接,该怎么办 <a href="/${localePath}/important">Locale-specific link</a&

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

${model.bookshelf.columnList[0].linkList[0].htmlMarkup}
没有什么突破性的。但是如果我们想在HTML标记中存储EL表达式呢?例如,如果要存储以下链接,该怎么办

<a href="/${localePath}/important">Locale-specific link</a>
。。。并将其显示在嵌套的JSP forEach中

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

${link.htmlMarkup}

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

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

由于我找不到任何现有的标签,我很快为这样一个评估标签提供了概念证明:

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;
    }
}
相关TLD:

<?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>

1
习俗
/WEB-INF/tlds/custom
单纯形
SimpleValtag
空的
价值
真的
真的
java.lang.Object
用法:

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

注意:

我已经使用Tomcat7.0.x/JSP2.1对其进行了测试,但正如您在源代码中看到的,没有特殊的错误处理等,因为它只是一些概念证明


在我的测试中,它使用
${sessionScope.attrName.prop1}
对会话变量起作用,也使用
${param.urlPar1}
对请求参数起作用,但由于它使用当前JSP的表达式计算器,我认为它应该适用于所有其他“正常”EL表达式,也一样。

您不需要自己以编程方式解析el表达式,您的标记应该通过在标记库中包含
true
来提供计算结果,例如

   <tag>   
      <name>mytag</name>

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

我的标签
我的属性
真的
真的

您是否可以添加一些有关应用程序接收HTTP请求时执行的代码序列的详细信息?我这样问是因为我不太明白问题的来龙去脉。如您所示,EL表达式应该是:(1)您的应用程序执行了一些代码,这些代码将这些属性放在一个JSP作用域中(2)您的标记在稍后的请求过程中由JSP提供。我使用的是Tomcat 6.0.X/JSP 2.1,这非常有效。谢谢这似乎非常有用。。。我很惊讶这样的东西不是任何标准taglib的一部分。谢谢。我也很惊讶,但可能是因为将该功能添加到任何自定义标记,甚至添加到“独立”标记并不复杂。
   <tag>   
      <name>mytag</name>

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