java web 项目中经常会遇到异常处理的问题,普遍的做法是使用全局异常处理,这样做有以下几种原因:
- 集中化处理:全局异常处理允许你在一个集中的地方处理整个应用程序中的异常。这有助于减少代码重复,因为你不必在每个可能抛出异常的方法中都编写相同的异常处理代码。
- 统一错误响应:通过全局异常处理,你可以确保应用程序在发生错误时返回统一的错误响应。这对于RESTful API特别重要,因为它允许客户端以统一的方式处理不同类型的错误。
- 日志记录:全局异常处理器是记录异常详细信息的理想位置。你可以在这里添加日志记录逻辑,以便在出现问题时能够轻松地跟踪和诊断问题。
- 跨控制器异常处理:如果你使用Spring MVC并定义了多个控制器,全局异常处理允许你在一个位置处理来自所有这些控制器的异常,而无需在每个控制器中都定义相同的异常处理逻辑。
- 异常转换:在某些情况下,你可能希望将原始异常转换为更具体或更通用的异常类型。全局异常处理允许你轻松地实现这种转换。
- 异常通知:除了返回错误响应外,全局异常处理还可以用于触发其他通知,如发送电子邮件、向外部系统发送消息或更新状态系统等。
- 简化测试:由于全局异常处理将异常处理逻辑集中在一个位置,因此更容易为这些逻辑编写单元测试,以确保它们按预期工作。
- 灵活性:全局异常处理通常允许你根据异常类型、请求参数或其他条件来定制响应。这提供了很大的灵活性,以满足各种业务需求。
其中有2种异常 404、405 需要特别注意,因为这2种异常不会经过 base controller 层处理,需要在上一层 spring 组件进行处理。
@ControllerAdvice
public class GlobalExceptionHandler{
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonResult doError(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Exception ex) {
ex.printStackTrace();
Map<String,Object> responseData = new HashMap<>();
if( ex instanceof BizException){
BizException bizException = (BizException)ex;
responseData.put("errCode",bizException.getErrCode());
responseData.put("errMsg",bizException.getErrMsg());
} else if(ex instanceof ServletRequestBindingException){
// 405
responseData.put("errCode",BizError.UNKNOWN_ERROR.getErrCode());
responseData.put("errMsg","url绑定路由错误!");
} else if(ex instanceof NoHandlerFoundException){
// 404
responseData.put("errCode",BizError.UNKNOWN_ERROR.getErrCode());
responseData.put("errMsg","访问路径不存在!");
} else {
responseData.put("errCode", BizError.UNKNOWN_ERROR.getErrCode());
responseData.put("errMsg",BizError.UNKNOWN_ERROR.getErrMsg());
}
return CommonResult.create(responseData,"fail");
}
}