`

SpringMVC 异常处理初探

 
阅读更多

Web应用中对于异常的处理方式与其他形式的应用并没有太大的不同――通过try/catch语句针对不同的异常进行相应处理。
但是在具体实现中,由于异常层次、种类繁杂,我们往往很难在Servlet、JSP层妥善的处理好所有异常情况,代码中大量的try/catch代码显得尤为凌乱。
我们通常面对下面两个主要问题:
1. 对异常实现集中式处理
典型情况:对数据库异常记录错误日志。
    一般处理方法无外两种,一是在各处数据库访问代码的异常处理中,加上日志记录语句。
    二是将在数据访问代码中将异常向上抛出,并在上层结构中进行集中的日志记录处理。
第一种处理方法失之繁琐、并且导致系统难以维护,假设后继需求为“对于数据库异常,需记录日志,并发送通知消息告知系统管理员”。
我们不得不对分散在系统中的各处代码进行整改,工作量庞大。
第二种处理方法实现了统一的异常处理,但如果缺乏设计,往往使得上层异常处理过于复杂。
这里,我们需要的是一个设计清晰、成熟可靠的集中式异常处理方案。
2. 对未捕获异常的处理
对于Unchecked Exception而言,由于代码不强制捕获,往往被程序员所忽略,如果运行期产生了Unchecked Exception,而代码中又没有进行相应的捕获和处理,
则我们可能不得不面对尴尬的500服务器内部错误提示页面。
这里,我们需要一个全面而有效的异常处理机制。

目前大多数服务器也都支持在Web.xml中通过<error-page>(Websphere/Weblogic)或者<error-code>(Tomcat)节点配置特定异常情况的显示页面。

<!-- 出错页面定义 -->   
    <error-page>   
        <exception-type>java.lang.Throwable</exception-type>   
        <location>/errors/500.jsp</location>   
    </error-page>   
    <error-page>   
        <error-code>500</error-code>   
        <location>/errors/500.jsp</location>   
    </error-page>
    <error-page>   
        <error-code>404</error-code>   
        <location>/errors/404.jsp</location>   
    </error-page>
    <error-page>   
        <error-code>403</error-code>   
        <location>/errors/403.jsp</location>   
    </error-page>
 

Spring MVC中提供了一个通用的异常处理机制,它提供了一个成熟的,简洁清晰的异常处理方案。如果基于Spring MVC开发Web应用,那么利用这套现成的机制进行异常处理也更加自然和有效。

一、Spring MVC中的异常处理:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:util="http://www.springframework.org/schema/util" 
        xsi:schemaLocation="
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/mvc    
          http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
          http://www.springframework.org/schema/util 
          http://www.springframework.org/schema/util/spring-util-3.0.xsd">
          
    <!-- 初始化bean,指定初始页面和成功后的页面 -->
	<bean id="simpleImplementsController"
		class="com.wy.controller.SimpleImplementsController" />
          
    <!-- 映射处理器 -->
	<bean id="simpleUrlMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/excep.do">simpleImplementsController</prop>
			</props>
		</property>
    </bean>   
    
    <!-- 视图解析器策略 和 视图解析器 -->
	<!-- 对JSTL提供良好的支持 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<!-- 默认的viewClass,可以不用配置
		<property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView" />
		 -->
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>      
          
       
	 <!-- 全局异常配置 start -->  
     <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
         <property name="exceptionMappings">  
             <props>  
                 <prop key="java.lang.Exception">errors/500</prop>  
                 <prop key="java.lang.Throwable">errors/404</prop>
				 <prop key="java.lang.RuntimeException">showError</prop>
				 <prop key="java.sql.SQLException">showDBError</prop> 
             </props>  
         </property>  
         <property name="statusCodes">  
             <props>  
                 <prop key="errors/500">500</prop>  
                 <prop key="errors/404">404</prop>  
             </props>  
         </property>  
         <!-- 设置日志输出级别,不定义则默认不输出警告等错误日志信息 -->  
         <property name="warnLogCategory" value="WARN" />  
         <!-- 默认错误页面,当找不到上面mappings中指定的异常对应视图时,使用本默认配置 -->  
         <property name="defaultErrorView" value="errors/500" />  
         <!-- 默认HTTP状态码 -->  
         <property name="defaultStatusCode" value="500" />  
     </bean>  
     <!-- 全局异常配置 end -->  
          
          
</beans>          
 


这里主要的类是SimpleMappingExceptionResolver类,和他的父类AbstractHandlerExceptionResolver类。
你也可以实现HandlerExceptionResolver接口,写一个自己的异常处理程序。

同时我们也可以为所有的异常指定一个默认的异常提示页面(通过defaultErrorView属性的配置),如果所抛出的异常在exceptionMappings中没有对应的映射,则Spring将用此默认配置显示异常信息。
注意这里配置的异常显示界面均仅包括主文件名,至于文件路径和后缀已经在viewResolver中指定。如/error/error表示/error/error.jsp
其中一句:request.getAttribute("exception"),key是exception,也是在SimpleMappingExceptionResolver类默认指定的,是可能通过配置文件修改这个值的。


 
二、把全局异常记录到日志中

在前面的配置中,其中有一个属性warnLogCategory,值是“SimpleMappingExceptionResolver类的全限定名”。
在SimpleMappingExceptionResolver类父类AbstractHandlerExceptionResolver类中找到这个属性的。
查看源码后得知:如果warnLogCategory不为空,spring就会使用apache的org.apache.commons.logging.Log日志工具,记录这个异常,级别是warn。
值:“org.springframework.web.servlet.handler.SimpleMappingExceptionResolver”,是“SimpleMappingExceptionResolver类的全限定名”。 
因为在log4j的配置文件中还要加入log4j.logger.org.springframework.web.servlet.handler.SimpleMappingExceptionResolver=WARN,
保证这个级别是warn的日志一定会被记录,即使log4j的根日志级别是ERROR。

 

 

  • 大小: 5.6 KB
分享到:
评论
2 楼 huangxiong2015 2014-10-28  
[b]发生的方式[/b]
1 楼 tanghanlin 2013-07-10  
你这个自己测试过吗?
我设置后还是无效

相关推荐

Global site tag (gtag.js) - Google Analytics