2010-03-10 80 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