一、使用HandlerExceptionResolver实现全局异常捕获
1、封装一个自己的业务异常类
public final class BizException extends RuntimeException {
private static final long serialVersionUID = 8342451586322744222L;
/**
* 业务异常码
*/
private Code codes;
/**
* 异常信息
*/
private String bizMsg;
/**
* 私有构造函数
*
* @param codes
* @param bizMessage
*/
private BizException(Code codes, String bizMessage) {
super(codes.getMessage() + ":" + bizMessage);
this.codes = codes;
this.bizMsg = bizMessage;
}
/**
* 静态工厂方法
*
* @return
*/
public static BizException create(Code code) {
return new BizException(code, null);
}
public static BizException create(Code code, String msg) {
return new BizException(code, msg);
}
public Code getCodes() {
return codes;
}
public void setCodes(Code codes) {
this.codes = codes;
}
public String getBizMsg() {
return bizMsg;
}
public void setBizMsg(String bizMsg) {
this.bizMsg = bizMsg;
}
}
2、定义自己的异常处理类MyExceptionHandler需要实现org.springframework.web.servlet.HandlerExceptionResolver接口。
public class MyExceptionHandler implements HandlerExceptionResolver {
private static final Logger LOG = LoggerFactory.getLogger(MyExceptionHandler.class);
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) {
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
try {
if (e instanceof BizException) {
LOG.error("业务异常:" + e.getMessage());
BizException ex = (BizException) e;
HttpResponse httpResponse = HttpResponse.create(ex.getCodes(),
StringUtils.isBlank(ex.getBizMsg()) ? "" : ex.getBizMsg());
httpServletResponse.getWriter().write(new Gson().toJson(httpResponse));
} else {
LOG.error("系统异常:" + e.getMessage());
e.printStackTrace();
HttpResponse httpResponse = HttpResponse.create(Code.SystemError, e.getMessage());
httpServletResponse.getWriter().write(new Gson().toJson(httpResponse));
}
} catch (IOException e1) {
}
return new ModelAndView();
}
}
3、在spring配置文件中定义bean
<!-- 异常处理类 -->
<bean name="myExceptionHandler" class="com.platform.common.MyExceptionHandler"/>
4、在代码中抛出自己的异常在resolveException方法中进行处理。
if (task == null) {
throw BizException.create(Code.NoProcess, "未执行通过上一步流程");
}
Code为自己定义的错误码枚举
二、使用@ControllerAdvice 、@ExceptionHandler两个注解来实现全局的异常捕获
// @ControllerAdvice
public class DefaultExceptionHandler {
// @ResponseStatus(HttpStatus.UNAUTHORIZED)
// @ExceptionHandler({ BizException.class, SizeLimitExceededException.class,
// MaxUploadSizeExceededException.class })
// @ResponseBody
public HttpResponse processUnauthorizedException(NativeWebRequest request, Exception e) {
if (e instanceof BizException) {
((BizException) e).getCodes();
} else if (e instanceof MaxUploadSizeExceededException || e instanceof SizeLimitExceededException) {
return HttpResponse.create(Code.SizeOver, "文件大小超过了10M");
}
return HttpResponse.create(Code.SystemError, e.getMessage());
// 判断异常类型,返回相应内容
}
}
@ControllerAdvice注解类似@Controller,后面加Advice可以理解为在Controller的方法上加的通知(后置)。在Controller的方法执行后,如果有异常抛出,会被该类的对应方法拦截。@ExceptionHandler注解表示拦截指定的异常,在@ExceptionHandler注解的方法中处理捕获的异常。返回同Controller。