您的位置:首页 > 编程语言 > Java开发

使用Spring实现异常统一处理【二】

2015-04-22 20:47 489 查看
在使用Spring实现异常统一处理【一】中,已给出一个关于返回json的异常处理方案,但此方案是根据http header的accept字段判断请求是否为json,如果我们accept字段不设置为“application/json”,则无法对json请求进行有效的异常统一处理。

在http://blog.csdn.net/m13321169565/article/details/7641978文章中,通过判断请求处理方法是否存在@ResponseBody注解,对Json等通过HttpMessageConverter处理的请求,进行区别异常处理。

结合以上经验,自定义一异常处理类,继承于SimpleMappingExceptionResolver,具体配置如下:

1、定义Java类

public class CustomSimpleMappingExceptionResolver extends
SimpleMappingExceptionResolver {

@Override
protected ModelAndView doResolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception exception) {

if (handler == null) {
return null;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();

if (method == null) {
return null;
}
Class<?> methodReturnType=method.getReturnType();
System.out.println("return type:"+methodReturnType.getName());
System.out.println("exception:"+exception.getCause()+","+exception.getLocalizedMessage());
ResponseBody responseBody = AnnotationUtils.findAnnotation(method,
ResponseBody.class);
if (methodReturnType.getName().equals("void")||responseBody != null) {
PrintWriter writer;
try {
String returnStr="{error:'"+exception.getMessage()+"'}";
writer = response.getWriter();
writer.write(returnStr);
writer.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

}

} else {
String viewName = super.determineViewName(exception, request);
System.out.println("viewName:"+viewName);

if (viewName != null) {// JSP格式返回

Integer statusCode = super.determineStatusCode(request,
viewName);
if (statusCode != null) {
super.applyStatusCodeIfPossible(request, response,
statusCode);
}
return super.getModelAndView(viewName, exception, request);
}
}
return null;

}// doResolveException

}


2、springmvc-servlet.xml(DispatcherServlet名称为springmvc)添加定义:

<bean id="exceptionResolver"
class="com.winssage.exception.CustomSimpleMappingExceptionResolver">
<property name="defaultErrorView" value="/exception/errorpage" />
<!--  定义异常处理页面用来获取异常信息的变量名,如果不添加exceptionAttribute属性,则默认为exception-->
<property name="exceptionAttribute" value="exception" />
<property name="exceptionMappings">
<props>
<!--不设置将根据defaultErrorView-->
<prop key="java.lang.exception">/exception/errorpage</prop>
<prop key="java.lang.RuntimeException">/exception/errorpage</prop>
</props>
</property>
<property name="order" value="0"/>
</bean>


3、errorpage.jsp定义:

<%@page contentType="text/html" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Hello World!error!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ${exception}
</h1>
</body>
</html>


问题总结:

1、在调试过程中,发现SimpleMappingExceptionResolver对某些异常捕捉不到,比如Spring MVC 的@RequestParam的类型映射不匹配,又比如在返回json进行httpMessageConverter处理时的异常,都捕捉不到。原因为:在xml定义中exceptionMappings漏定义了 <prop
key="java.lang.RuntimeException">/exception/errorpage</prop>。

2、添加上配置 <prop key="java.lang.RuntimeException">/exception/errorpage</prop>后,对json进行HttpMessageConverter转换时,又报java.lang.IllegalStateException:
STREAM错误,目前该问题还未解决。

3、所以用 SimpleMappingExceptionResolver希望对系统所有异常进行统一处理,仍存在问题,只能配合DefaultMappingExceptionResolver一起使用。

DefaultMappingExceptionResolver的配置:在Web.xml中添加:

<error-page>
<error-code>500</error-code>
<location>/error/show.do</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/errorpage.jsp</location>
</error-page>
注:error-page可以指向jsp也可指向一个http request

DefaultMappingExceptionResolver方式的errorpage.jsp定义:

<%@page contentType="text/html" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
response.setStatus(200); // 200 = HttpServletResponse.SC_OK
%>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Hello World!error!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
${pageContext.exception }</h1>
</body>
</html>
其中,<% response.setStutus(200);%>是为了解决IE的友好报错界面而设置的。 IE的友好报错界面真讨厌
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐