关于spring MVC的全局异常处理
参考: https://www.cnblogs.com/junzi2099/p/8022058.html
1: 问题引入在RequestMapping, 如下代码会抛出ArrayIndexOutOfBoundsException
不然会报错。
2: 如果不对异常进行处理,异常会抛到前台,通过如下代码,可以将异常处理。
@ControllerAdvice
public class SpringExceptionHandler {
/**
* 全局处理Exception
* 错误的情况下返回500
* @param ex
* @param req
* @return
*/
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<Object> handleOtherExceptions(final Exception ex, final WebRequest req) {
BaseResp baseResp = new BaseResp(ErrorCode.FAILED, "系统内部错误");
return new ResponseEntity<Object>(baseResp, HttpStatus.EXPECTATION_FAILED);
}
}
3: Filter的核心的ApplicationFilterChain ,本对象管理着一批系统定义,或自定义的Filter。
当tomcat调用
ApplicationFilterChain> doFilter -> 第一个Filter-> ApplicationFilterChain ->Filter.
所以Filter比较多时,调用的栈比较深。 可以看出ApplicationFilterChain是入口。当有Filter时,一直循环调用,一直到Filter用完时,再调用.service(HttpServlet.java:742)
这个时候spring mvc 才开始。
[2021-07-01 11:36:53,066] ERROR Forwarding to error page from request [/queryAlarmListForFixedMsg] due to exception [10]
java.lang.ArrayIndexOutOfBoundsException: 10
at com.cmcc.ctw.restful.AlarmHisAPI.queryAlarmListForFixedMsg(AlarmHisAPI.java:274) ~[classes/:1.0.0-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_171]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_171]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.3.8.jar:5.3.8]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[servlet-api.jar:?]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.3.8.jar:5.3.8]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[servlet-api.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:8.5.34]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) ~[tomcat-websocket.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:8.5.34]
at com.cmcc.ctw.filter.OperateAuthFilter.doFilter(OperateAuthFilter.java:113) ~[classes/:1.0.0-SNAPSHOT]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:8.5.34]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:8.5.34]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:8.5.34]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) [spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) [spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) [spring-boot-2.5.1.jar:2.5.1]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.8.jar:5.3.8]
at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) [spring-boot-2.5.1.jar:2.5.1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.34]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.8.jar:5.3.8]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.8.jar:5.3.8]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.34]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.34]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [catalina.jar:8.5.34]
4: 定义ControllerAdvice 算得上是Interceptor 吗, 其实还算不上。 可以看ContollerAdvice使用时管理对象,还是要DispatcherServlet这个springMVC 管理。
5: dispatcherServlet对servlet作了极大的增强。
5.1 Servlet 接口,定义了servelt有创建,销毁,还定义了应该得到getServletConfig
5.2 GenericServlet 实现了一个,与协议无关的servelt. 引入了log 打印,实现了servletConfig的一些接口。
5.3 HttpServlet 是一个抽象的httpServet给web使用。将servelet通用的ServletRequest req, ServletResponse res 传成了,HttpServletRequest req, HttpServletResponse resp
实现了GET, PUT, POST等方法,但是实现得很简单。基本就是简单的输出。
5.4 HttpServletBean 实现了init-param 的配置
5.5 FrameworkServlet 与springApplication集成, 管理了WebApplicationContext, 发布了请求事件。
5.6 DispatcherServlet http handlers /controllers的核心实现类。
5.6.1 基于JAVA Bean的配置机制
可以使用任何的HanlderMapping, 有BeanNameUrlHandlerMapping 和RequestMappingHandlerMappin
可以使用任何的HandlerAdapter;
通过HandlerExceptionResolver做异常处理
ViewResolver 视图转换器。
6: DispatcherServlet的创建
创建是在ServletWebServerApplicationContext 父类,会创建webServer 时。通过初始化器。
这类初始始化器叫做 ServletContextInitializer 其主要做用就是传入servletContext 来配置servletContext.
其中的FilterRegistrationBean 就是一个Filter的初始化器.
DispatcherServletRegistrationBean 作用是将一个servlet注册到servletContext中去,与
FilterRegistrationBean 效果相似。