前言
大家在使用Spring框架编写Controller的时候,都会遇到这样一种情况,就是想做一个全局异常处理,目的是不要每个人都单独拦截处理系统类的异常。
正文
下面我将介绍一种方法,利用HandlerExceptionResolver做一个统一的异常拦截处理,当然这种方式只适用于没有手动拦截异常请求的情况,如果某一个Controller自己拦截并处理了异常,不会被这个统一异常处理所覆盖到。
实现
步骤一,准备Resolver
package com.op.exception;
import com.google.gson.Gson;
import com.op.common.ResultJson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
*/
public class ServiceExceptionResolver implements HandlerExceptionResolver {
private static final Logger logger = LoggerFactory.getLogger(ServiceExceptionResolver.class);
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
try {
PrintWriter printWriter = response.getWriter();
//返回结果封装类
ResultJson resultJson = new ResultJson();
//业务异常的时候,按照各业务自身的异常消息进行返回
if (ex instanceof ServiceDataException) {
resultJson.setCode(((ServiceDataException) ex).getCode());
resultJson.setMessage(ex.getMessage());
} else {//非业务异常的时候,统一处理为系统异常消息进行返回
resultJson.setCode(500);
logger.error("系统异常,请稍后尝试!", ex);
resultJson.setMessage("系统异常,请稍后尝试!");
}
Gson gson = new Gson();
String json = gson.toJson(resultJson);
logger.error("全局异常处理!返回结果:{}", json, ex);
response.setContentType("application/json;charset=UTF-8");
//返回json数据。
printWriter.println(json);
printWriter.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return null;
}
}
这个示例围绕两个异常点来设计:
一个是业务异常,即开发者自己拦截的可以预知的异常;
一个是非业务异常,即开发者未拦截的不可预知的异常;
从实现中可以看出来这个异常处理最终应该返回到指定的页面,但是我们这里作为对前端提供的API接口,我们会统一处理为Json的形式并直接返回此内容。因此这里的return null并不是没有处理,而是直接将返回内容输出到了终端!
步骤二,返回处理结果类ResultJson
示例中涉及到一个ResultJson返回处理结果类,其实其内容很简单:
package com.op.common;
public class ResultJson {
public int code;
public String message;
public Object data;
public ResultJson(int code, String message) {
this.code = code;
this.message = message;
}
public ResultJson() {
this.code = Constants.SUCCESS_CODE;
this.message = "success";
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public ResultJson setData(Object data) {
this.data = data;
return this;
}
}
步骤三,配置该Bean
<bean class="com.op.exception.ServiceExceptionResolver"/>
在你的配置文件中定义该Bean即可,Spring容器会扫描所有实现了HandlerExceptionResolver接口的异常处理器,统一处理!