一、异常处理
(一)、局部异常处理 ——Controller里面使用@ExceptionHandler注解
注意:对于文件上传的异常,默认这里是无法处理的 出现异常的地方不在本Controller内
* 可以在multipartResolver 中配置<property name="resolveLazily" value="true"/>后捕获
当 resolveLazily为false(默认)时,会立即调用 parseRequest() 方法对请求数据进行解析, 然后将解析结果封装到 DefaultMultipartHttpServletRequest中;
而当resolveLazily为 true时,会在DefaultMultipartHttpServletRequest的initializeMultipart()方法调用parseRequest()方法对请求数据进行解析,
而initializeMultipart()方法又是被getMultipartFiles()方法调用,
即当需要获取文件信息时才会去解析请求数据。
(二)、全局异常处理 —— @ControllerAdvice + @ExceptionHandler
目的:把单个Controller中@ExceptionHandler ,搬到@ControllerAdvice中,可以管理更多的Controller
@ControllerAdvice 指定 Controller 范围主要依靠自身的几个属性实现:
1. basePackages:指定一个或多个包,这些包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理。下面三种写法等价:
@ControllerAdvice("com.gx.controller")
@ControllerAdvice(value = "com.gx.controller")
@ControllerAdvice(basePackages = "com.gx.controller")
2. basePackageClasses:是 basePackages 的一种变形,指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理。
@ControllerAdvice(basePackageClasses = FileUploadController.class)
3. assignableTypes:指定一个或多个 Controller 类,这些类被该 @ControllerAdvice 管理。
@ControllerAdvice(assignableTypes = {FileUploadController.class})
4. annotations:指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理。
@ControllerAdvice(annotations = {RestController.class})
(三)、全局异常处理 —— SimpleMappingExceptionResolver
该方法处理全局异常,只要有对应的异常抛出,就会使用这个bean进行处理。使用SimpleMappingExceptionResolver的话,只要在springmvc配置文件中添加配置就可以了。
<!--SimpleMappingExceptionResolver 全局异常配置-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 默认的异常界面,如果不是特殊指定的异常,都显示这个界面 -->
<property name="defaultErrorView" value="/simpleError/simpleDefaultErr" />
<!-- 异常变量的名称,界面上可以使用这个来输出异常信息 -->
<property name="exceptionAttribute" value="ex" />
<!-- 指定特殊异常,并为特殊异常指定特定的界面 -->
<property name="exceptionMappings">
<props>
<!--key为需要特殊指定的异常的完整类名,prop元素中指定页面的路径-->
<!--文件上传相关异常-->
<prop key="org.springframework.web.multipart.MultipartException">/simpleError/simpleFileUploadErr</prop>
<!--演示除0异常-->
<prop key="java.lang.ArithmeticException">/simpleError/arithmeticErr</prop>
</props>
</property>
</bean>
(四)、全局异常处理 —— 实现HandlerExceptionResolver接口
SimpleMappingExceptionResolver也是实现了HandlerExceptionResolver接口。
HandlerExceptionResolver的实现类会捕捉到 @Controller 方法执行时发生的异常,处理后返回 ModelAndView 作为结果视图,因此可以通过它来定制异常视图。
HandlerExceptionResolver只能捕获 @Controller 层发生的异常(包括 @Controller 调用 @Service 发生的异常)。而其他地方的异常,比如访问了一个不存在的路径,不会被HandlerExceptionResolver 捕获,
二、SpringMVC拦截器Interceptor
(一)、拦截器(interceptor)和过滤器(filter)的区别
过滤器(filter)
- Filter属于Servlet技术,只要是web工程都可以使用
- filter主要由于对所有请求过滤
- Filter的执行时机早于Interceptor
拦截器(interceptor)
- Interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用
- Interceptor通常由于对SpringMVC的请求进行拦截
- Interceptor只能拦截dispatcherServlet处理的请求
(二)、拦截器的基本使用
1、实现HandlerInterceptor接口,可根据选择重写preHandle,postHandle,afterCompletion方法
- preHandle方法
作用: 用于对拦截到的请求进行预处理,方法接收布尔(true,false)类型的返回值,返回true:放行,false:不放行。
执行时机: 在处理器方法执行前执行
方法参数:
1. request 请求对象
2. response 响应对象
3. handler 拦截到的处理器方法
- postHandle方法
作用: 用于对拦截到的请求进行后处理,可以在方法中对模型数据和视图进行修改
执行时机: 在处理器的方法执行后,视图渲染之前
方法参数:
1. request 请求对象
2. response 响应对象
3. handler 拦截到的处理器方法
4. ModelAndView 处理器方法返回的模型和视图对象,可以在方法中修改模型和视图
- afterCompletion方法
作用: 用于在整个流程完成之后进行最后的处理,如果请求流程中有异常,可以在方法中获取对象
执行时机: 视图渲染完成后(整个流程结束之后)
方法参数:
1. request 请求参数
2. response 响应对象
3. handler 拦截到的处理器方法
4. ex 异常对象
2、在springMVC-servlet.xml中配置拦截器
<!--SpringMVC 拦截器配置(可以多个)-->
<mvc:interceptors>
<!--配置拦截器-->
<mvc:interceptor>
<!--配置拦截的资源-->
<mvc:mapping path="/**"/>
<!--配置拦截器bean对象-->
<bean class="完整类名"/>
</mvc:interceptor>
</mvc:interceptors>
(三)、拦截器链及其执行顺序
拦截器链的概念 如果多个拦截器能够对相同的请求进行拦截,则多个拦截器会形成一个拦截器链,主要理解拦截器链中各个拦截器的执行顺序。
拦截器链中多个拦截器的执行顺序 拦截器链中的多个拦截器的执行顺序,和拦截器的配置顺序有关,先配置的先执行。
单个拦截器:preHandle -> Handler执行 -> postHandle -> 视图渲染 -> afterCompletion
多个拦截器:preHandle1、preHandle2、....preHandleN -> Handler执行 -> postHandleN、...postHandle1 -> 视图渲染 -> afterCompletionN、...afterCompletion1
(四)、拦截器放行静态资源
<mvc:interceptor>
<!--配置拦截的资源-->
<mvc:mapping path="/**"/>
<!--排除不拦截的资源-->
<mvc:exclude-mapping path="/**/*.png"/>
<mvc:exclude-mapping path="/**/*.jpg"/>
<mvc:exclude-mapping path="/**/*.css"/>
<mvc:exclude-mapping path="/**/*.js"/>
<!--....-->
<!--配置拦截器bean对象-->
<bean class="com.gx.interceptor.MyInterceptor1"/>
</mvc:interceptor>
配置中/**/*.png类似的配置,含义为,访问当前项目中任意层级的以.png结尾的资源拦截器都不拦截。