使用Spring实现异常统一处理【三】--java.lang.IllegalStateException: STREAM问题的解决

在《使用Spring实现异常统一处理【二】》中,在处理JSON转换的异常时,自定义异常处理类,自个就报java.lang.IllegalStateException: STREAM错误,原因为:在该自定义异常处理类中,使用了response.getWriter()进行错误信息输出,而Spring的MappingJackson2HttpMessageConverter应该通过response.getOutputStream(),已获取了输出流。

在servlet标准中,是不允许同时使用response.getWriter()和response.getOutputStream()的,所以报java.lang.IllegalStateException: STREAM错误。

       原因知道了,解决方案就有谱了:在获取response.getWriter()出错时,就改用response.getOutputStream()输出流。

       关键代码

String returnStr="{error:'"+exception.getMessage()+"'}";
try {
<span style="white-space:pre">	</span>writer = response.getWriter();
<span style="white-space:pre">	</span>writer.write(returnStr);
<span style="white-space:pre">	</span>writer.flush();
<span style="white-space:pre">	</span>writer.close();
} catch (Exception e) {
<span style="white-space:pre">	</span>try {
<span style="white-space:pre">	</span>OutputStream output=response.getOutputStream();
<span style="white-space:pre">	</span>output.write(returnStr.getBytes("UTF-8"));
<span style="white-space:pre">	</span>output.flush();
<span style="white-space:pre">	</span>output.close();
<span style="white-space:pre">	</span>} catch (Exception e1) {
<span style="white-space:pre">	</span>e1.printStackTrace();
<span style="white-space:pre">	</span>}
}

 

       完整代码

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();
		ResponseBody responseBody = AnnotationUtils.findAnnotation(method,
				ResponseBody.class);
		if (methodReturnType.getName().equals("void")||responseBody != null) {
			PrintWriter writer;
			String returnStr="{error:'"+exception.getMessage()+"'}";
			try {
				writer = response.getWriter();
				writer.write(returnStr);
			    writer.flush();
				writer.close();
			} catch (Exception e) {
				try {		
					OutputStream output=response.getOutputStream();
					output.write(returnStr.getBytes("UTF-8"));
					output.flush();
					output.close();					
				} catch (Exception e1) {
					e1.printStackTrace();
				}
			}

		} else {
			String viewName = super.determineViewName(exception, request);			
			
			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 new ModelAndView();

	}// doResolveException

}


<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>
		<!-- order=0,则无法在先在Controller通过注解进行异常处理,order=1刚刚好-->
		<property name="order" value="1"/> 
</bean>

<%@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>



  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值