我昨天也沿着类似的路线询问question。在那个问题中,我被建议有一个全局过滤器(我已经拥有)。
所以我有一个如下的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>
'control'通过我拥有的全局过滤器来到上面的JSP。它chain.doFilter()
块中包含try/catch
。当exception
发生时,它会重定向到Error.jsp。
当错误发生时...它没有被集中式错误页面捕获,也没有被过滤器捕获。我认为过滤器没有捕获它,因为当过滤器'调用'jsp ...时还没有错误。
我知道在JSP中调用DB是很糟糕但是我处理的是很多遗留代码。
在此方案中,如何将错误转到集中错误页面?此外,JSP没有导入错误页面。我不希望将错误页面导入到所有JSP的选项我希望有一个更通用的解决方案。
答案 0 :(得分:3)
JSP中的异常无法很好地处理,因为更改响应为时已晚。 JSP作为一种视图技术,负责整个响应。它发送响应头和响应内容。发送响应标头后,则表示不返回。即使过滤器也不会有帮助。
每当在JSP中途发生异常时,响应将突然中止,客户端将面临空白页面或半页面,并且异常最高只能记录到服务器日志中。每当尝试重定向/转发/显示错误页面时,可能沿着IllegalStateException: response already committed
,这是不可能的,因为响应已经提交。
简而言之:不要在JSP文件中编写原始Java代码。将它们放在Java类中,例如(in)直接在Servlet中。在JSP显示之前处理它。这样就有足够的空间来改变响应的目的地。
如果您坚持使用JSP进行业务逻辑(我不建议这样做),那么另一种方法是将所有业务逻辑放在JSP文件的顶部之前,之前< / em>将任何模板文本(HTML等)发送到响应。如果幸运的话,每当抛出异常时,servletcontainer都能够将响应更改为错误页面。
答案 1 :(得分: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>