2010-03-10 72 views
4

我昨天也沿着類似的方式詢問了question。在那個問題中,我被建議有一個全局過濾器(我已經有過)。如何在JSP中捕獲和拋出錯誤

所以我有一個JSP像下面

....code...code 
..tags...html...code 
Object [] res = iBatisDAO.getReport_pging(null,null,0,null); //call to DB 
...more code... 
...tags...end 

在上面的代碼,我故意傳遞null是因爲我希望它失敗,當它失敗我希望它去我們集中的錯誤頁面。我有我的web.xml

<error-page> 
    <exception-type>com.ibatis.common.jdbc.exception.NestedSQLException</exception-type> 
    <location>/errorpages/Error.jsp</location> 
    </error-page> 
    <error-page> 
    <exception-type>org.springframework.dao.DataAccessException</exception-type> 
    <location>/errorpages/Error.jsp</location> 
    </error-page> 
    <error-page> 
    <exception-type>javax.servlet.ServletException</exception-type> 
    <location>/errorpages/Error.jsp</location> 
    </error-page> 
    <error-page> 
    <exception-type>java.sql.SQLException</exception-type> 
    <location>/errorpages/Error.jsp</location> 
    </error-page> 
    <error-page> 
    <exception-type>org.springframework.jdbc.UncategorizedSQLException</exception-type> 
    <location>/errorpages/Error.jsp</location> 
    </error-page> 

'控制'通過我有一個全局過濾器來到上述JSP。它有chain.doFilter()包裹在try/catch區塊。當exception發生它重定向到Error.jsp。

當錯誤發生時...它不會被中央錯誤頁面捕獲,也不會被過濾器捕獲。我認爲過濾器沒有捕獲它,因爲當過濾器'調用'jsp ...那裏沒有錯誤。

我知道調用DB在JSP內部是壞的,但我正在處理大量的遺留代碼。

在這種情況下,我能做些什麼來讓錯誤進入集中錯誤頁面?而且,JSP沒有導入錯誤頁面。我不希望導入一個錯誤頁面到所有JSP的選項,我想有一個更通用的解決方案。

回答

0

您採取了錯誤的做法。您的JSP文件中不得有任何邏輯處理代碼(業務邏輯)。 JSP是一種視圖技術。使用servlet或某些動作/組件框架(Struts2/Spring MVC/JSF /等)來處理業務邏輯。

至於過濾器的方法 - 它是一個很好的解決方案,但必須對過濾器(使用<filter-mapping>)映射到/*

<filter> 
    <filter-name>exceptionFilter</filter-name> 
    <filter-class>com.yourpackage.YourFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>exceptionFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+0

它被映射到那個。但是因爲發生了異常內部的JSP ...過濾器如何捕獲該異常?... – drake 2010-03-10 13:33:46

+0

@drake JSP被轉換爲一個Servlet。所以它發生在一個servlet中,在'chain.doFilter()'之後處理。請給出由異常生成的堆棧跟蹤。 – Bozho 2010-03-10 13:58:38

+0

異常消息是:'org.springframework.jdbc.UncategorizedSQLException:SqlMapClient操作;未歸類SQL []的SQLException; SQL狀態[null];錯誤代碼[17004];'我在web.xml中捕獲的內容。現在我注意到,代碼是在chain.doFilter的catch塊中進行的,但是,在我嘗試執行'response.sendRedirect'時,在該catch塊中,它因爲響應已經設置而失敗。有沒有解決的辦法? – drake 2010-03-10 16:13:26

3

例外在JSP中不能很好地處理,因爲它是來不及變化響應。 JSP作爲一種視圖技術負責整個響應。它發送響應標題和響應內容。當發送響應頭時,它是的一個點,不返回。即使過濾器在這裏也無濟於事。

每當JSP中途發生異常時,響應將突然中止,客戶端將面對空白頁或半頁頁面,並且異常最多隻能記錄到服務器日誌中。每當嘗試重定向/轉發/顯示錯誤頁面時,可能沿着IllegalStateException: response already committed,因爲響應已經提交。

簡而言之:不要在JSP文件中編寫原始Java代碼。將它們放在Java類中,例如(in)直接在Servlet中。它在之前得到處理JSP顯示。這樣就有足夠的空間來改變響應的目的地。

如果您在使用JSP實現業務邏輯(我不推薦)堅持,那麼還有一個辦法是把所有的業務邏輯到JSP文件的頂部之前的任何模板文本(HTML和等等)將被髮送到響應。如果幸運的話,只要拋出異常,servletcontainer就可以將響應更改爲錯誤頁面。

+0

感謝您的解釋。我明白那個。但是我正在處理超過100多箇舊版JSP,並且無法將這些全部更改爲現在取出業務邏輯。我注意到,代碼是在'chain.doFilter'的catch塊中進行的,但是,如果我嘗試執行'response.sendRedirect',它會失敗,因爲響應已經設置。有沒有辦法解決這個問題? – drake 2010-03-10 16:14:41

+0

不是。這是一個不歸路。您無法針對某個請求發送多個回覆。 – BalusC 2010-03-10 16:32:16

+0

這就是牛。正如你所說,我注意到,如果調用DB是JSP中的第一件事,而不是在中間,那麼它會通過web.xml中的錯誤頁面聲明來捕獲。然而,如果它位於中間的某個地方,那麼它不會被它們抓住。這背後的原因是什麼? – drake 2010-03-10 17:10:56

相關問題