2015-06-08 80 views
1

我們注意到,在JSP中未聲明的變量可能會導致非常糟糕的表現。你可以讓JSP在未聲明的變量上崩潰嗎?

請看下面的示例代碼:

<c:if test="..."> 
    <c:set var="isSaleCategory" value="true"/> 
</c:if> 

<c:forEach items="${ARTICLES}" var="article" varStatus="status"> 
    <c:if test="${not empty articlePrice && (!isSaleCategory)}"> 

的代碼了5-6秒來處理並返回結果。

如果我們首先初始化變量,執行時間降低到幾毫秒:

<c:set var="isSaleCategory" value="false"/> 

<c:if test="..."> 
    <c:set var="isSaleCategory" value="true"/> 
</c:if> 

<c:forEach items="${ARTICLES}" var="article" varStatus="status"> 
    <c:if test="${not empty articlePrice && (!isSaleCategory)}"> 

現在,我們不介意這麼多將此代碼添加到初始化變量,但棘手的部分是找到他們。 ..在沒有循環的頁面上我們不會看到第二個+響應時間,但是在重負載下,當然這會增加不必要的負載。

有沒有一種方法,使當它蹣跚而行未初始化的變量類似上面JSP處理失敗?

+0

在那裏沒有NPE的?看起來更像是第二次測試中的一些錯誤處理,其中由於第一次測試失敗而無法設置「isSaleCategory」。如果你想補充空指針檢查作爲第二個測試A或條件?'(isSaleCategory爲null ||!isSaleCategory)' – Antoniossss

+0

有多大你的文章收藏?似乎很奇怪變量強制應該是那麼昂貴。 –

+0

@Antoniossss JSP相當寬容(這是本例中的核心問題),並且不要爲這些場景拋出任何異常。 – Marcus

回答

1

爲什麼它訪問未聲明的變量時的速度慢的問題是,ELResolvers挖得很深,試圖找到該變量。

見試圖很多非聲明的變量,這需要大量的時間,當http://grepcode.com/file/repo1.maven.org/maven2/org.apache.tomcat/tomcat-jsp-api/8.0.15/javax/servlet/jsp/el/ScopedAttributeELResolver.java#58

許多ClassNotFoundExceptions拋出。要解決這個

一種方式是寫一個簡單的放變量作爲解決如果與null值頁面範圍內沒有找到一個自定義ELResolver,這樣可以防止框架從挖得更深。

private static class NullOnMissingVariableELResolver extends ELResolver 
{ 
    /** {@inhericDoc} */ 
    @Override 
    public Object getValue(ELContext context, Object base, Object property) 
    { 
     if (base == null && property != null) 
     { 
      String key = property.toString(); 
      PageContext page = (PageContext) context.getContext(JspContext.class); 
      Object result = page.findAttribute(key); 

      if (result == null) 
      { 
       context.setPropertyResolved(true); 
      } 
     } 

     return null; 
    } 

這當然帶有一些注意事項,如果您有使用這些特殊類查找的模板,它們將不起作用!

+0

很棒的建議!在開發模式中,我們可以設置ELResolver來拋出異常並修復未設置的變量。 – Brimstedt

+0

找到根本原因:https://tomcat.apache.org/migration-8.html#JavaServer_Pages_2.3 – Brimstedt

0

我發現了更多的問題,現在看來,這似乎在Tomcat中8: https://tomcat.apache.org/migration-8.html#JavaServer_Pages_2.3

另一種解決方案是在前面加上範圍的變量,所以不是:

${isSaleCategory} 

使用

${requestScope.isSaleCategory} 

雖然這意味着對jsp文件的很多改變,所以Marcus對客戶ELResolver的回答對f ind這些發生。