springmvc提供了HandlerExceptionResolver接口,可以对异常进行统一处理。springmvc有几个实现HandlerExceptionResolver接口的类,对异常进行处理,我们可以参照源码,进行自定义的异常统一处理。
一、springmvc实现HandlerExceptionResolver接口的类
- DefaultHandlerExceptionResolver ,它根据web.xml 状态配置直接将异常转化成相应的状态码,转到相应的异常处理页面。
- AnnotationMethodHandlerExceptionResolver ,支持通过注解的方式处理异常,如:@ExceptionHandler
- SimpleMappingExceptionResolver,是springmvc提供的简单异常统一处理,需要在spring配置文件中配置,如:
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面-->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面传递异常信息属性 -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key -->
<property name="exceptionMappings">
<props>
<prop key="com.simple.exception.ServiceException">error-service</prop>
</props>
</property>
</bean>
二、自定义异常统一处理
1.新建MyExceptionHandler自定义异常统一处理类
package com.simple.exception;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
public class MyExceptionHandler implements HandlerExceptionResolver{
private final Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
if (ex instanceof HttpRequestMethodNotSupportedException) {
try {
return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,
response, handler);
} catch (IOException e) {
log.error("RequestMethodNotSupported异常", e);
}
}
String uri = request.getRequestURI();
log.error("异常请求路径:" + uri);
log.error("异常信息:", ex);
//根据请求路径,返回不同请求设备的错误页面
if (null != uri && uri.contains("/appwap")) {
return new ModelAndView("error/appwap-500");
}else if (null != uri && uri.contains("/pcweb")){
return new ModelAndView("error/pcweb-500");
}
return null;
}
/**
* 根据DefaultHandlerExceptionResolver中对RequestMethod异常的处理
* 实现RequestMethod统一异常处理,当发生RequestMethod异常时,如HEAD请求,MyExceptionHandler会将
* 堆栈信息打印出来,其实只要warn级别就可以了
* @param ex
* @param request
* @param response
* @param handler
* @return
* @throws IOException
*/
protected ModelAndView handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException ex,
HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
log.warn(ex.getMessage());
String[] supportedMethods = ex.getSupportedMethods();
if (supportedMethods != null) {
response.setHeader("Allow", StringUtils.arrayToDelimitedString(supportedMethods, ", "));
}
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, ex.getMessage());
return new ModelAndView();
}
}
2.spring xml中配置
```xml
<bean id="myExceptionHandler" class="com.simple.exception.MyExceptionHandler"></bean>
3.测试结果
2017-09-17 15:45:19 [com.simple.exception.MyExceptionHandler]-[ERROR] 异常请求路径:/test/hello
2017-09-17 15:45:19 [com.simple.exception.MyExceptionHandler]-[ERROR] 异常信息:
java.lang.Exception: 自定义异常处理
at com.simple.controller.HelloWorldController.hello(HelloWorldController.java:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
……