使用Spring中的ExceptionHandlerExceptionResolver进行统一的异常处理
2015-03-25 17:09
549 查看
还是直接上代码说明:
1。 编写相关AnnotationHandlerMethodExceptionResolver异常处理类
[java]
view plaincopyprint?
package com.pss.res.base.exceptionresolver;
import com.pss.res.client.base.constants.BusiStatusCons;
import com.pss.res.client.base.domain.ServiceResponse;
import com.pss.res.common.util.DateHelper;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 不必在Controller中对异常进行处理,抛出即可,由此异常解析器统一控制。<br>
* ajax请求(有@ResponseBody的Controller)发生错误,输出JSON。<br>
* 页面请求(无@ResponseBody的Controller)发生错误,输出错误页面。<br>
* 需要与AnnotationMethodHandlerAdapter使用同一个messageConverters<br>
* Controller中需要有专门处理异常的方法。
*
*
* */
public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver {
private String defaultErrorView;
public String getDefaultErrorView() {
return defaultErrorView;
}
public void setDefaultErrorView(String defaultErrorView) {
this.defaultErrorView = defaultErrorView;
}
protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) {
if (handlerMethod == null) {
return null;
}
Method method = handlerMethod.getMethod();
if (method == null) {
return null;
}
//如果定义了ExceptionHandler则返回相应的Map中的数据
ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception);
ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class);
if (responseBodyAnn != null) {
try {
ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class);
if (responseStatusAnn != null) {
HttpStatus responseStatus = responseStatusAnn.value();
String reason = responseStatusAnn.reason();
if (!StringUtils.hasText(reason)) {
response.setStatus(responseStatus.value());
} else {
try {
response.sendError(responseStatus.value(), reason);
} catch (IOException e) { }
}
}
// 如果没有ExceptionHandler注解那么returnValue就为空
if (returnValue == null) {
ServiceResponse res = new ServiceResponse();
res.setResultCode(BusiStatusCons.STATUS_FAILURE);
res.setResultDesc("系统异常:" + exception.getLocalizedMessage());
res.setTimestamp(DateHelper.getCurrentTimeStamp(null));
handleResponseError(res, request, response);
return new ModelAndView();
}
return handleResponseBody(returnValue, request, response);
} catch (Exception e) {
return null;
}
}
if( null == returnValue) {
returnValue = new ModelAndView();
if (null == returnValue.getViewName()) {
returnValue.setViewName(defaultErrorView);
}
}
return returnValue;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map value = returnValue.getModelMap();
HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
if (acceptedMediaTypes.isEmpty()) {
acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
}
MediaType.sortByQualityValue(acceptedMediaTypes);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
Class<?> returnValueType = value.getClass();
List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
if (messageConverters != null) {
for (MediaType acceptedMediaType : acceptedMediaTypes) {
for (HttpMessageConverter messageConverter : messageConverters) {
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
messageConverter.write(value, acceptedMediaType, outputMessage);
return new ModelAndView();
}
}
}
}
if (logger.isWarnEnabled()) {
logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private ModelAndView handleResponseError(ServiceResponse returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
if (acceptedMediaTypes.isEmpty()) {
acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
}
MediaType.sortByQualityValue(acceptedMediaTypes);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
Class<?> returnValueType = returnValue.getClass();
List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
if (messageConverters != null) {
for (MediaType acceptedMediaType : acceptedMediaTypes) {
for (HttpMessageConverter messageConverter : messageConverters) {
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
messageConverter.write(returnValue, acceptedMediaType, outputMessage);
return new ModelAndView();
}
}
}
}
if (logger.isWarnEnabled()) {
logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);
}
return null;
}
}
其中以下的代码,需要根据具体情况进行改变。
[java]
view plaincopyprint?
// 如果没有ExceptionHandler注解那么returnValue就为空
if (returnValue == null) {
ServiceResponse res = new ServiceResponse();
res.setResultCode(BusiStatusCons.STATUS_FAILURE);
res.setResultDesc("系统异常:" + exception.getLocalizedMessage());
res.setTimestamp(DateHelper.getCurrentTimeStamp(null));
handleResponseError(res, request, response);
return new ModelAndView();
}
2。 xml配置文件中,需要进行的相关配置操作,如下:
[java]
view plaincopyprint?
<bean id="handlerExceptionResolver" class="com.pss.res.base.exceptionresolver.AnnotationHandlerMethodExceptionResolver">
<property name="defaultErrorView" value="error/500"/> <!--错误页面-->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<!-- JSON转换器无需设置mediaType,由外部客户端调用时,手动设置相关mediaType -->
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
3。 测试类中,只要controller中有异常抛出,即会被捕获,并显示在浏览器中。
[java]
view plaincopyprint?
@Controller
@RequestMapping("/exeHandler")
public class ExeHandlerController {
@RequestMapping(value="/test")
public @ResponseBody Object getAllIndusType(IndusTypeReqVO indusTypeReqVO) throws Exception{
System.err.println("cccccc");
throw new Exception("这边出错了。");
// return null;
}
}
还是直接上代码说明:
1。 编写相关AnnotationHandlerMethodExceptionResolver异常处理类
[java]
view plaincopyprint?
package com.pss.res.base.exceptionresolver;
import com.pss.res.client.base.constants.BusiStatusCons;
import com.pss.res.client.base.domain.ServiceResponse;
import com.pss.res.common.util.DateHelper;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 不必在Controller中对异常进行处理,抛出即可,由此异常解析器统一控制。<br>
* ajax请求(有@ResponseBody的Controller)发生错误,输出JSON。<br>
* 页面请求(无@ResponseBody的Controller)发生错误,输出错误页面。<br>
* 需要与AnnotationMethodHandlerAdapter使用同一个messageConverters<br>
* Controller中需要有专门处理异常的方法。
*
*
* */
public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver {
private String defaultErrorView;
public String getDefaultErrorView() {
return defaultErrorView;
}
public void setDefaultErrorView(String defaultErrorView) {
this.defaultErrorView = defaultErrorView;
}
protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) {
if (handlerMethod == null) {
return null;
}
Method method = handlerMethod.getMethod();
if (method == null) {
return null;
}
//如果定义了ExceptionHandler则返回相应的Map中的数据
ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception);
ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class);
if (responseBodyAnn != null) {
try {
ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class);
if (responseStatusAnn != null) {
HttpStatus responseStatus = responseStatusAnn.value();
String reason = responseStatusAnn.reason();
if (!StringUtils.hasText(reason)) {
response.setStatus(responseStatus.value());
} else {
try {
response.sendError(responseStatus.value(), reason);
} catch (IOException e) { }
}
}
// 如果没有ExceptionHandler注解那么returnValue就为空
if (returnValue == null) {
ServiceResponse res = new ServiceResponse();
res.setResultCode(BusiStatusCons.STATUS_FAILURE);
res.setResultDesc("系统异常:" + exception.getLocalizedMessage());
res.setTimestamp(DateHelper.getCurrentTimeStamp(null));
handleResponseError(res, request, response);
return new ModelAndView();
}
return handleResponseBody(returnValue, request, response);
} catch (Exception e) {
return null;
}
}
if( null == returnValue) {
returnValue = new ModelAndView();
if (null == returnValue.getViewName()) {
returnValue.setViewName(defaultErrorView);
}
}
return returnValue;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map value = returnValue.getModelMap();
HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
if (acceptedMediaTypes.isEmpty()) {
acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
}
MediaType.sortByQualityValue(acceptedMediaTypes);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
Class<?> returnValueType = value.getClass();
List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
if (messageConverters != null) {
for (MediaType acceptedMediaType : acceptedMediaTypes) {
for (HttpMessageConverter messageConverter : messageConverters) {
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
messageConverter.write(value, acceptedMediaType, outputMessage);
return new ModelAndView();
}
}
}
}
if (logger.isWarnEnabled()) {
logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);
}
return null;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private ModelAndView handleResponseError(ServiceResponse returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
if (acceptedMediaTypes.isEmpty()) {
acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
}
MediaType.sortByQualityValue(acceptedMediaTypes);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
Class<?> returnValueType = returnValue.getClass();
List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
if (messageConverters != null) {
for (MediaType acceptedMediaType : acceptedMediaTypes) {
for (HttpMessageConverter messageConverter : messageConverters) {
if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
messageConverter.write(returnValue, acceptedMediaType, outputMessage);
return new ModelAndView();
}
}
}
}
if (logger.isWarnEnabled()) {
logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);
}
return null;
}
}
package com.pss.res.base.exceptionresolver; import com.pss.res.client.base.constants.BusiStatusCons; import com.pss.res.client.base.domain.ServiceResponse; import com.pss.res.common.util.DateHelper; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Method; import java.util.Collections; import java.util.List; import java.util.Map; /** * 不必在Controller中对异常进行处理,抛出即可,由此异常解析器统一控制。<br> * ajax请求(有@ResponseBody的Controller)发生错误,输出JSON。<br> * 页面请求(无@ResponseBody的Controller)发生错误,输出错误页面。<br> * 需要与AnnotationMethodHandlerAdapter使用同一个messageConverters<br> * Controller中需要有专门处理异常的方法。 * * * */ public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver { private String defaultErrorView; public String getDefaultErrorView() { return defaultErrorView; } public void setDefaultErrorView(String defaultErrorView) { this.defaultErrorView = defaultErrorView; } protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) { if (handlerMethod == null) { return null; } Method method = handlerMethod.getMethod(); if (method == null) { return null; } //如果定义了ExceptionHandler则返回相应的Map中的数据 ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception); ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class); if (responseBodyAnn != null) { try { ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class); if (responseStatusAnn != null) { HttpStatus responseStatus = responseStatusAnn.value(); String reason = responseStatusAnn.reason(); if (!StringUtils.hasText(reason)) { response.setStatus(responseStatus.value()); } else { try { response.sendError(responseStatus.value(), reason); } catch (IOException e) { } } } // 如果没有ExceptionHandler注解那么returnValue就为空 if (returnValue == null) { ServiceResponse res = new ServiceResponse(); res.setResultCode(BusiStatusCons.STATUS_FAILURE); res.setResultDesc("系统异常:" + exception.getLocalizedMessage()); res.setTimestamp(DateHelper.getCurrentTimeStamp(null)); handleResponseError(res, request, response); return new ModelAndView(); } return handleResponseBody(returnValue, request, response); } catch (Exception e) { return null; } } if( null == returnValue) { returnValue = new ModelAndView(); if (null == returnValue.getViewName()) { returnValue.setViewName(defaultErrorView); } } return returnValue; } @SuppressWarnings({ "unchecked", "rawtypes" }) private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map value = returnValue.getModelMap(); HttpInputMessage inputMessage = new ServletServerHttpRequest(request); List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept(); if (acceptedMediaTypes.isEmpty()) { acceptedMediaTypes = Collections.singletonList(MediaType.ALL); } MediaType.sortByQualityValue(acceptedMediaTypes); HttpOutputMessage outputMessage = new ServletServerHttpResponse(response); Class<?> returnValueType = value.getClass(); List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters(); if (messageConverters != null) { for (MediaType acceptedMediaType : acceptedMediaTypes) { for (HttpMessageConverter messageConverter : messageConverters) { if (messageConverter.canWrite(returnValueType, acceptedMediaType)) { messageConverter.write(value, acceptedMediaType, outputMessage); return new ModelAndView(); } } } } if (logger.isWarnEnabled()) { logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes); } return null; } @SuppressWarnings({ "unchecked", "rawtypes" }) private ModelAndView handleResponseError(ServiceResponse returnValue, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpInputMessage inputMessage = new ServletServerHttpRequest(request); List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept(); if (acceptedMediaTypes.isEmpty()) { acceptedMediaTypes = Collections.singletonList(MediaType.ALL); } MediaType.sortByQualityValue(acceptedMediaTypes); HttpOutputMessage outputMessage = new ServletServerHttpResponse(response); Class<?> returnValueType = returnValue.getClass(); List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters(); if (messageConverters != null) { for (MediaType acceptedMediaType : acceptedMediaTypes) { for (HttpMessageConverter messageConverter : messageConverters) { if (messageConverter.canWrite(returnValueType, acceptedMediaType)) { messageConverter.write(returnValue, acceptedMediaType, outputMessage); return new ModelAndView(); } } } } if (logger.isWarnEnabled()) { logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes); } return null; } }
其中以下的代码,需要根据具体情况进行改变。
[java]
view plaincopyprint?
// 如果没有ExceptionHandler注解那么returnValue就为空
if (returnValue == null) {
ServiceResponse res = new ServiceResponse();
res.setResultCode(BusiStatusCons.STATUS_FAILURE);
res.setResultDesc("系统异常:" + exception.getLocalizedMessage());
res.setTimestamp(DateHelper.getCurrentTimeStamp(null));
handleResponseError(res, request, response);
return new ModelAndView();
}
// 如果没有ExceptionHandler注解那么returnValue就为空 if (returnValue == null) { ServiceResponse res = new ServiceResponse(); res.setResultCode(BusiStatusCons.STATUS_FAILURE); res.setResultDesc("系统异常:" + exception.getLocalizedMessage()); res.setTimestamp(DateHelper.getCurrentTimeStamp(null)); handleResponseError(res, request, response); return new ModelAndView(); }
2。 xml配置文件中,需要进行的相关配置操作,如下:
[java]
view plaincopyprint?
<bean id="handlerExceptionResolver" class="com.pss.res.base.exceptionresolver.AnnotationHandlerMethodExceptionResolver">
<property name="defaultErrorView" value="error/500"/> <!--错误页面-->
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<!-- JSON转换器无需设置mediaType,由外部客户端调用时,手动设置相关mediaType -->
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="handlerExceptionResolver" class="com.pss.res.base.exceptionresolver.AnnotationHandlerMethodExceptionResolver"> <property name="defaultErrorView" value="error/500"/> <!--错误页面--> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" /> <!-- JSON转换器无需设置mediaType,由外部客户端调用时,手动设置相关mediaType --> <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> </list> </property> </bean>
3。 测试类中,只要controller中有异常抛出,即会被捕获,并显示在浏览器中。
[java]
view plaincopyprint?
@Controller
@RequestMapping("/exeHandler")
public class ExeHandlerController {
@RequestMapping(value="/test")
public @ResponseBody Object getAllIndusType(IndusTypeReqVO indusTypeReqVO) throws Exception{
System.err.println("cccccc");
throw new Exception("这边出错了。");
// return null;
}
}
@Controller @RequestMapping("/exeHandler") public class ExeHandlerController { @RequestMapping(value="/test") public @ResponseBody Object getAllIndusType(IndusTypeReqVO indusTypeReqVO) throws Exception{ System.err.println("cccccc"); throw new Exception("这边出错了。"); // return null; } }
相关文章推荐
- 使用Spring中的ExceptionHandlerExceptionResolver进行统一的异常
- 利用HandlerExceptionResolver对SpringMVC进行统一异常处理
- 使用Spring中的ExceptionHandlerExceptionResolver进行统一的异常处理
- 使用Spring MVC HandlerExceptionResolver处理异常
- 使用Spring MVC HandlerExceptionResolver处理异常
- 使用Spring MVC HandlerExceptionResolver处理异常
- 使用Spring MVC HandlerExceptionResolver处理异常
- Spring 异常处理HandlerExceptionResolver
- Spring MVC的Controller统一异常处理:HandlerExceptionResolver
- Spring MVC的Controller统一异常处理:HandlerExceptionResolver
- HandlerExceptionResolver统一捕获系统异常做处理
- Spring 异常处理HandlerExceptionResolver
- Java深入 - Spring 异常处理HandlerExceptionResolver
- Spring MVC的Controller统一异常处理:HandlerExceptionResolver
- Spring MVC的Controller统一异常处理:HandlerExceptionResolver
- spring mvc的controller统一异常处理handlerExceptionResolver
- Spring MVC的Controller统一异常处理:HandlerExceptionResolver
- Java深入 - Spring 异常处理HandlerExceptionResolver
- Java深入 - Spring 异常处理HandlerExceptionResolver
- Spring中的@ControllerAdvice注解配合@ExceptionHandler使用实现异常处理