解析Tomcat 6、7在EL表達式解析時存在的一個Bug。本站提示廣大學習愛好者:(解析Tomcat 6、7在EL表達式解析時存在的一個Bug)文章只能為提供參考,不一定能成為您想要的結果。以下是解析Tomcat 6、7在EL表達式解析時存在的一個Bug正文
明天在做數據分頁顯示的時刻碰到了一個成績,經由測試,證明是Tomcat 6的一個bug,我所用的版本為:apache-tomcat-6.0.36,和7.0.30均能復現。上面具體描寫一下這個bug:
該bug是在JSTL<c:forEach>標簽中發明的,後來剖析是EL表達式完成時發生的成績。jsp頁面中有一個list須要遍歷,這個list的類型為ArrayList<String>,我在個中放置的數據為(為便利我寫成數組的情勢):["1","...","4","5","6","7","8","...","10"],這是一個很罕見的帶頁碼縮略的分頁導航。在展現這些數據的時刻我應用了上面的代碼:
<c:forEach var="looper" items="${pageHelper.pageList}">
<c:choose>
<c:when test="${looper eq pageHelper.pageDot}">
<p>分頁游標的 點點點</p>
</c:when>
<c:when test="${looper eq pageHelper.pageNo}">
<p>以後頁為第${looper}頁面</p>
</c:when>
<c:otherwise>
<p>分頁游標:${looper}</p>
</c:otherwise>
</c:choose>
</c:forEach>
這裡pageHelper就是分頁組件,個中預設了pageDot為"...",pageNo為以後的頁碼(假定為6),其他情形直接顯示分頁游標。在輪回遍歷中只不外應用了最根本的前提斷定語句,因為pageList在界說中曾經明白指出是List<String>,按邏輯應當eq是依照字符串斷定的,然則竟然出異常了:
javax.el.ELException: Cannot convert ... of type class java.lang.String to class java.lang.Long
為何會湧現“類型轉換毛病”呢?經由過程剖析代碼走向,當進入輪回後,list中的第一條數據是“1”,而pageHelper.pageNo為long型,此時tomcat的EL表達式解析器會把looper類型轉換為Long型而不是把pageHelper.pageNo類型轉換為String停止比擬,當遍歷到下一元素時,looper="...",這時候looper的類型曾經肯定,比擬的時刻tomcat還要試圖將looper轉換為Long類型,因而就失足了。
為此我專門寫了一個實例代碼:
<c:forEach var="looper" items="${pageHelper.pageList}">
<c:choose>
<c:when test="${looper eq fn:trim(pageHelper.pageDot)}">
<p>分頁游標的 點點點</p>
</c:when>
<c:when test="${looper eq fn:trim(pageHelper.pageNo)}">
<p>以後頁為第${looper}頁面</p>
</c:when>
<c:otherwise>
<p>分頁游標:${looper}</p>
</c:otherwise>
</c:choose>
</c:forEach>
很簡略,每次比擬的時刻都把後者用fn:trim辦法停止去除閣下非可見字符。相當於強迫轉換為String類型,此時tomcat又可以正常解析代碼,並未報錯。
異樣的一套代碼,我將其安排到resin中發明不管是修正前照樣修正後都能正常運轉,可見,應當是tomcat的bug。
示例代碼:點擊下載
讓tomcat報錯的演示地址:/bug/show.do
防止此bug的辦法演示地址:/bug/avoid.do
以上地址前能夠須要加上項目稱號(詳細取決於你若何安排該項目)
p; android:text="播放" /> <Button
android:id="@+id/PauseButton"
android:layout_width="80px"
android:layout_height="wrap_content"
android:layout_x="210px"
android:layout_y="300px"
android:text="暫停" />
</AbsoluteLayout>