1、自定义异常处理,首先需要一个自定义系统异常类,一般都是继承Exception类,下面列两个自定义的异常类。
简单的异常类:
public class CustomException extends Exception{
//异常信息
public String message;
public CustomException(String message){
super(message);
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
复杂点的异常类:这里的ResultInfo是系统封装的结果类
/**
* 自定义系统异常
* @author KL
*
*/
public class ExceptionResultInfo extends Exception{
//系统统一使用的结果类,包括了 提示信息类型和信息内容
private ResultInfo resultInfo;
public ResultInfo getResultInfo() {
return resultInfo;
}
public void setResultInfo(ResultInfo resultInfo) {
this.resultInfo = resultInfo;
}
public ExceptionResultInfo(ResultInfo resultInfo){
//调用父类Exception的构造函数将resultInfo.getMessage()当做新的异常信息构造
super(resultInfo.getMessage());
this.resultInfo=resultInfo;
}
}
2、有了异常类接下来就可以指定异常处理器,当系统遇到异常,最简单的一级一级往上抛出,dao抛给service、service抛给controller,controller抛给前端控制器,前端控制器调用全局异常处理器。
全局异常处理器处理思路:解析出异常类型,如果该异常类型是系统自定义的异常,直接取出异常信息,在错误页面展示。如果该异常类型不是系统自定义的异常,构造一个自定义的异常类型(信息为“未知错误”)
Springmvc提供了一个HandlerExceptionResolver接口,只要实现这个接口,Springmvc就会默认为这是一个全局的异常处理。当然一个系统中,只能由一个全局的异常处理。可以看出这个异常处理器将错误信息封装成json数据。
/**
* 全局异常处理器,全局一般需要在web.xml中配置,关闭spring默认的异常处理器。
* @author KL
*
*/
public class ExceptionResolverCustom implements HandlerExceptionResolver{
// json转换器
// 将异常信息转json
private HttpMessageConverter jsonMessageConverter;
public HttpMessageConverter getJsonMessageConverter() {
return jsonMessageConverter;
}
//依赖注入三种方式之一setter注入
public void setJsonMessageConverter(
HttpMessageConverter jsonMessageConverter) {
this.jsonMessageConverter = jsonMessageConverter;
}
// 前端控制器调用此方法执行异常处理
// handler,执行的action类就包装了一个方法(对应url的方法)
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
// 输出 异常信息
ex.printStackTrace();
// 转成springmvc底层对象(就是对action方法的封装对象,只有一个方法(因为springMvc面向方法开发))
HandlerMethod handlerMethod=(HandlerMethod) handler;
// 取出方法
Method method = handlerMethod.getMethod();
// 判断方法是否返回json
// 只要方法上有responsebody注解表示返回json,
// 没有responsebody注解是返回jsp页面,两者都会异常处理方式不同,具体如下
// 查询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);
String view = "/base/error";
//异常代码
int messageCode = exceptionResultInfo.getResultInfo().getMessageCode();
//如果是106则跳转到登陆
if(messageCode==106){
//跳转到登陆
view = "/base/login";
}
// 将异常信息在异常页面显示
request.setAttribute("exceptionResultInfo",
exceptionResultInfo.getResultInfo());
// 转向错误页面
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("exceptionResultInfo",
exceptionResultInfo.getResultInfo());
modelAndView.setViewName(view);//逻辑视图名,error.jsp
return modelAndView;
}
// 异常信息解析方法(一种是系统异常,一种是Runtime异常)
private ExceptionResultInfo resolveExceptionCustom(Exception ex) {
ResultInfo resultInfo=null;
if (ex instanceof ExceptionResultInfo) {
//抛出系统自定义异常
resultInfo=((ExceptionResultInfo) ex).getResultInfo();
}else {
// 重新构造“未知错误”异常,比如runtimeException
resultInfo = new ResultInfo();
resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL);
resultInfo.setMessage("未知错误!");
}
return new ExceptionResultInfo(resultInfo);
}
// 将异常信息转json输出
private ModelAndView resolveJsonException(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod,
Exception ex) {
// 异常信息解析
ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex);
HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
try {
//将exceptionResultInfo对象转成json输出,这里使用spring异常处理的工具
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();
}
}
3、在springmvc的配置文件中注入这个bean,前端控制器就会调用这个全局异常处理器。
<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
bean>
<bean id="handlerExceptionResolver"
class="yycg.base.process.exception.ExceptionResolverCustom">
<property name="jsonMessageConverter" ref="jsonMessageConverter" />
bean>
4、接下来就可以把异常一层一层抛出如下
dao:dao抛出异常给service
public interface SysuserMapperCustom {
//查询用户列表
public List findSysuserList(SysuserQueryVo sysuserQueryVo) throws Exception;
//查询总数
public int findSysuserCount(SysuserQueryVo sysuserQueryVo) throws Exception;
}
service:service抛出异常给Controller
public interface UserService {
// 根据条件查询用户信息
public List findSysuserList(SysuserQueryVo sysuserQueryVo)
throws Exception;
// 根据条件查询列表的总数
public int findSysuserCount(SysuserQueryVo sysuserQueryVo) throws Exception;
}
Controller:Controller抛出给DispatcherServlet然后交由统一异常处理
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/sysuserquery")
public String queryuser(Model model) throws Exception{
}
这篇文章贴出了部分代码,主要想阐明整体思路,让我们新手对springMVC的自定义异常处理器有一个好的认识,同时自己做一些笔记,增强记忆,本人菜鸟一枚,如有不正确的地方希望大神指正。