全局异常处理
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都要继承它才行。
整个思路就是这样子的,你可以继续完善。。。。
推荐阅读
-
OPPO A31曝光:搭载联发科P35处理器的4230mAh大电池新机
-
远程办公如何提高效率?AMD推荐这些锐龙处理器
-
AI提升480倍 ARM发布针对Cortex-M平台的首款微神经网络处理器
-
被蚂蚁咬了怎么办?处理方法以及注意事项
-
ORACLE DATAGUARD中手工处理日志v$archive_GAP的方法
-
编写函数处理user_list,新方法
-
oracle 11g导出数据时报ORA 1455错误的处理方法
-
Ubuntu 18.04 使用apt-get 华为源支持 arm64 鲲鹏处理器
-
iPhone 11现身?A13处理器GB4跑分曝光:主频提升7%、单核性能增加12%
-
分析Python的Django框架的运行方式及处理流程