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

Spring自定义全局异常处理器

2017-04-27 23:06 423 查看
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<ExceptionResultInfo> jsonMessageConverter;

public HttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() {
return jsonMessageConverter;
}
//依赖注入三种方式之一setter注入
public void setJsonMessageConverter(
HttpMessageConverter<ExceptionResultInfo> 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);

t
ca44
ry {
//将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,前端控制器就会调用这个全局异常处理器。

<!-- json转换器 -->
<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
</bean>

<!-- 统一异常处理类,需要在web.xml中将默认的异常处理器关闭 -->
<bean id="handlerExceptionResolver"
class="yycg.base.process.exception.ExceptionResolverCustom">
<!-- 注入一个json转换器 -->
<property name="jsonMessageConverter" ref="jsonMessageConverter" />
</bean>


4、接下来就可以把异常一层一层抛出如下

dao:dao抛出异常给service

public interface SysuserMapperCustom {

//查询用户列表
public List<SysuserCustom> findSysuserList(SysuserQueryVo sysuserQueryVo) throws Exception;
//查询总数
public int findSysuserCount(SysuserQueryVo sysuserQueryVo) throws Exception;
}


service:service抛出异常给Controller

public interface UserService {

// 根据条件查询用户信息
public List<SysuserCustom> 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的自定义异常处理器有一个好的认识,同时自己做一些笔记,增强记忆,本人菜鸟一枚,如有不正确的地方希望大神指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息