2013-01-12 155 views
4

我們將HTML標記存儲在XML文檔中,並使用JiBX解析。我們也使用Spring,當這些對象中的一個被添加到模型中時,我們可以通過EL在JSP中訪問它。評估請求屬性中的EL表達式

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

沒什麼突破性的。但是如果我們想要在HTML標記中存儲EL表達式呢?例如,如果我們想要存儲以下鏈接呢?

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

...並將其顯示在其中LocalePath是請求屬性的JSP中。

或者更有趣的是,如果我們想存儲以下內容呢?

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」標籤?令牌替換在第一個例子中起作用,但不在第二個例子中,並且不是很健壯。

+0

您可以添加一些關於應用程序收到HTTP請求時執行的代碼序列的更多詳細信息嗎?我問這是因爲我沒有完全理解問題的背景。如您所示,EL表達式應該進行評估:(1)您的應用程序執行了一些將這些屬性放入其中一個JSP範圍的代碼。(2)您的標記稍後在請求過程中由JSP提供。 – EJK

回答

2

如果我理解它是正確的:您正在尋找一種方法來評估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; 
    } 
} 

相關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> 

用法:

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

注:

我已經使用Tomcat 7.0.x/JSP 2.1對它進行了測試,但正如您在源代碼中看到的,沒有特殊的錯誤處理等,因爲它只是一些概念驗證。

在我的測試中,它的工作使用${sessionScope.attrName.prop1}會話變量,並使用${param.urlPar1}請求參數,但它採用了目前JSP的表達式求值,我想這應該對所有其他「正常」的EL表達式的工作,太。

+0

我正在使用Tomcat 6.0.X/JSP 2.1,並且這個工作完美。謝謝!這似乎非常有用......我很驚訝這樣的事情不是任何標準taglib的一部分。 –

+0

謝謝。我也很驚訝,但也許是因爲將這個功能添加到任何自定義標籤,甚至是「獨立」標籤都不是很複雜。 – jCoder

0

您不需要自己編程解析el表達式,應通過在標記庫中包含<rtexprvalue>true</rtexprvalue>來爲您的標記提供評估結果,例如,

<tag> 
     <name>mytag</name> 

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