全局异常处理

Spring 统一异常处理有 3 种方式,分别为:

1.使用 @ ExceptionHandler 注解

2.实现 HandlerExceptionResolver 接口

3.使用 @controlleradvice 注解

我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。

处理思路

如上图所示,系统的dao、service、controller出现异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理。springmvc提供全局异常处理器(一个系统只有一个异常处理器)进行统一异常处理。

全局异常处理器
整个系统只有一个,
使用方法:
1)需要实现一个接口
HandlerExceptionResolver
2)需要在springmvc中配置。

处理逻辑:
捕获整个系统中发生的异常。
1、异常写入日志文件
2、及时通知开发人员。发邮件、短信。
展示一个错误页面,例如:您的网络故障,请重试。

====================项目中的应用================


我们进行处理:

public class GlobalExceptionResolver implements HandlerExceptionResolver {
	public static final Logger logger= LoggerFactory.getLogger(GlobalExceptionResolver.class);
	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		//1.打印控制台
		ex.printStackTrace();
		//2.写日志
		logger.error("系统发生异常",ex);
		//3.发邮件,发短信
		//使用jmail工具包
		//4.给用户展示友好界面
		ModelAndView modelandView = new ModelAndView();
		modelandView.setViewName("error/exception");
		return modelandView;
	}
}
<!-- 全局异常处理器 -->
<bean class="cn.e3mall.search.controller.GlobalExceptionResolver"/>


日志文件记录:

[INFO ] 2018-04-16 13:55:47,280 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter     - Looking for @ControllerAdvice: WebApplicationContext for namespace 'e3-search-web-servlet': startup date [Mon Apr 16 13:55:42 CST 2018]; root of context hierarchy
 [INFO ] 2018-04-16 13:55:47,358 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter     - Looking for @ControllerAdvice: WebApplicationContext for namespace 'e3-search-web-servlet': startup date [Mon Apr 16 13:55:42 CST 2018]; root of context hierarchy
 [INFO ] 2018-04-16 13:55:47,562 org.springframework.web.servlet.DispatcherServlet     - FrameworkServlet 'e3-search-web': initialization completed in 4986 ms
 [ERROR] 2018-04-16 13:56:57,774 cn.e3mall.search.controller.GlobalExceptionResolver     - 系统发生异常
 java.lang.ArithmeticException: / by zero
	at cn.e3mall.search.controller.SearchController.searchItemList(SearchController.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

 springmvc中自带了一个异常处理器叫SimpleMappingExceptionResolver,该处理器实现了HandlerExceptionResolver 接口,全局异常处理器都需要实现该接口。我们要使用这个自带的异常处理器,首先得在springmvc.xml文件中配置该处理器:

<!-- springmvc提供的简单异常处理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
     <!-- 定义默认的异常处理页面 -->
    <property name="defaultErrorView" value="/WEB-INF/jsp/error.jsp"/>
    <!-- 定义异常处理页面用来获取异常信息的变量名,也可不定义,默认名为exception --> 
    <property name="exceptionAttribute" value="ex"/>
    <!-- 定义需要特殊处理的异常,这是重要点 --> 
    <property name="exceptionMappings">
        <props>
            <prop key="ssm.exception.CustomException">/WEB-INF/jsp/custom_error.jsp</prop>
        </props>
        <!-- 还可以定义其他的自定义异常 -->
    </property>
</bean>
从上面的配置来看,最重要的是要配置特殊处理的异常,这些异常一般都是我们自定义的,根据实际情况来自定义的异常,然后也会跳转到不同的错误显示页面显示不同的错误信息。这里就用一个自定义异常CustomException来说明问题,定义如下:
//定义一个简单的异常类
public class CustomException extends Exception {
    //异常信息
    public String message;

    public CustomException(String message) {
        super(message);
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
接下来就是写测试程序了,还是使用查询的例子,如下: 

异常

 @ExceptionHandler注解实现异常处理

  还有一种是使用注解的方法,我大概说一下思路,因为这种方法对代码的入侵性比较大,我不太喜欢用这种方法。 
  首先写个BaseController类,并在类中使用@ExceptionHandler注解声明异常处理的方法,如:

 

复制代码
public class BaseController { 
    @ExceptionHandler  
    public String exp(HttpServletRequest request, Exception ex) { 
    //异常处理
    //......
    }
}
复制代码

 

然后将所有需要异常处理的Controller都继承这个BaseController,虽然从执行来看,不需要配置什么东西,但是代码有侵入性,需要异常处理的Controller都要继承它才行。 

整个思路就是这样子的,你可以继续完善。。。。


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37499059/article/details/79959531
文章标签: 全局异常处理器
个人分类: 后端编程
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭