1.准备
- 自定义异常类(包括系统提示信息和错误内容)
public class ExceptionResultInfo extends Exception {
// 系统统一使用的结果类,包括了 提示信息类型和信息内容
private ResultInfo resultInfo;
public ExceptionResultInfo(ResultInfo resultInfo) {
super(resultInfo.getMessage());
this.resultInfo = resultInfo;
}
public ResultInfo getResultInfo() {
return resultInfo;
}
public void setResultInfo(ResultInfo resultInfo) {
this.resultInfo = resultInfo;
}
}
- 系统提示信息
public class ResultInfo
{
public static final int TYPE_RESULT_FAIL = 0;//失败
public static final int TYPE_RESULT_SUCCESS = 1;//成功
public static final int TYPE_RESULT_WARN = 2;//警告
public static final int TYPE_RESULT_INFO = 3;//提示信息
public ResultInfo(){}
/**
* 消息提示类型(成功,失败...)
*/
private int type;
/**
* 提示代码(自定义错误代码)
*/
private int messageCode;
/**
* 提示信息(错误代码对应的错误信息)
*/
private String message;
/**
* 提示消息对应操作的序号,方便用户查找问题,通常用于在批量提示信息中标识记录序号
*/
private int index;
/**
* 提交后得到到业务数据信息从而返回给页面
*/
private Map<String,Object> sysdata = new HashMap<String, Object>();
/**
* 提示信息明细列表
*/
private List<ResultInfo> details;
}
2.分析
全局异常处理:在service层抛出自定义异常或未知异常,在controller层捕获并解析异常,并返回
思路:用try,catch捕获异常,先判断抛出的是不是自定义异常,如果是,则解析异常信息;如果不是,创建一个“未知错误异常”
3.方法
1,service层抛出自定义异常
2,controller捕获并解析异常
用try catch捕获异常后,判断异常是否是自定义异常,如果不是,创建一个“未知错误异常”:
3,上述方法较为麻烦,需要在每个controller中加入上述内容,而springmvc提供了一个统一异常处理器机制,其前端控制器调用适配器(action)过程中如果发生异常,就交给异常处理器执行,因此可以创建一个统一异常处理器,这样在action(controller)中就不需要try,catch了。由于mvc的action返回的数据有两种,一种是json,一种是jsp,则流程如下:
思路:判断是否为自定义异常,如果不是,构建一个“未知异常”,如果是,判断要求返回数据是不是json,是,则解析异常信息,如果不是,转为json再解析。
实现:
public class ExceptionResolverCustom implements HandlerExceptionResolver {
// json转换器
// 将异常信息转json
private HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter;
// 前端控制器调用此方法执行异常处理
// handler,执行的action类就包装了一个方法(对应url的方法)
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// 输出 异常信息
ex.printStackTrace();
// 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法)
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 取出方法
Method method = handlerMethod.getMethod();
// 判断方法是否返回json
// 只要方法上有responsebody注解表示返回json
// 查询method是否有responsebody注解
ResponseBody responseBody = AnnotationUtils.findAnnotation(method,
ResponseBody.class);
if (responseBody != null) {
// 将异常信息转json输出
return this.resolveJsonException(request, response, handlerMethod,
ex);
}
// 这里说明action返回的是jsp页面
// 解析异常
ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
// 将异常信息在异常页面显示
request.setAttribute("exceptionResultInfo",
exceptionResultInfo.getResultInfo());
// 转向错误页面
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exceptionResultInfo",
exceptionResultInfo.getResultInfo());
modelAndView.setViewName("/base/error");// 逻辑视图名
return modelAndView;
}
// 异常信息解析方法
private ExceptionResultInfo resolveExceptionCustom(Exception ex) {
ResultInfo resultInfo = null;
if (ex instanceof ExceptionResultInfo) {
// 抛出的是系统自定义异常
resultInfo = ((ExceptionResultInfo) ex).getResultInfo();
} else {
// 重新构造“未知错误”异常
resultInfo = new ResultInfo();
resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);
resultInfo.setMessage("未知错误!");
}
return new ExceptionResultInfo(resultInfo);
}
// 将异常信息转json输出
private ModelAndView resolveJsonException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// 解析异常
ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
try {
//将exceptionResultInfo对象转成json输出
jsonMessageConverter.write(exceptionResultInfo, MediaType.APPLICATION_JSON, outputMessage);
} catch (HttpMessageNotWritableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new ModelAndView();
}
public HttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() {
return jsonMessageConverter;
}
public void setJsonMessageConverter(
HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter) {
this.jsonMessageConverter = jsonMessageConverter;
}
}
配置:
在springmvc.xml中配置
<!-- json转换器 -->
<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
</bean>
<!-- 统一异常处理类 -->
<bean id="handlerExceptionResolver"
class="yycg.base.process.exception.ExceptionResolverCustom">
<!-- 注入一个json转换器 -->
<property name="jsonMessageConverter" ref="jsonMessageConverter" />
</bean>
在web.xml中屏蔽springmvc自动注册的异常处理器
<!-- springmvc的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation不是必须的, 如果不配置contextConfigLocation, springmvc的配置文件默认在:WEB-INF/servlet的name+"-servlet.xml" -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<!-- 屏蔽springmvc自动注册的异常处理器 -->
<init-param>
<param-name>detectAllHandlerExceptionResolvers</param-name>
<param-value>false</param-value>
</init-param>
<!-- <load-on-startup>1</load-on-startup> -->
</servlet>
测试:
dao service action 方法全部都throws Exception即可,service内部的话同3.1