业务逻辑层-异常处理
通常,建议自定义异常,用于表示在业务逻辑层中的“失败”(或错误),而不要使用已知的异常类型,避免捕获、处理不准确!
可以在项目的根包下创建ex.ServiceException
类,继承自RuntimeException
:
public class ServiceException extends RuntimeException {
// 生成5个构造方法
}
Spring MVC统一处理异常
Spring MVC框架提供了统一处理异常的机制,使得每种类型的异常在处理时,只需要编写1次相关代码即可。
通常,统一处理异常的代码会写在专门的类中,此类应该添加@ControllerAdvice
,则类中相关的方法会在处理每个请求时生效!
由于目前采取前后端分离的模式,处理异常后的响应方式是响应正文,所以,还应该使用@ResponseBody
,或者,使用@RestControllerAdvice
,它同时具有@ControllerAdvice
和@ResponseBody
的效果。
@RestControllerAdvice
public class GlobalExceptionHandler {
}
然后,在此类中添加处理异常的方法:
- 注解:必须添加
@ExceptionHandler
注解,表示此方法是统一处理异常的方法 - 访问权限:应该使用
public
- 返回值类型:参考处理请求的方法
- 方法名称:自定义
- 参数列表:至少包含1个异常类型的参数,表示需要处理的异常,或理解为Spring MVC框架在调用控制器的方法后捕获的异常,另外,可按需添加
HttpServletRequest
、HttpServletResponse
等少量特定类型的参数
所以,完整的处理异常的代码为:
package cn.tedu.csmall.product.ex.handler;
import cn.tedu.csmall.product.ex.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler
public String handleServiceException(ServiceException e) {
log.debug("处理ServiceException:{}", e.getMessage());
return e.getMessage();
}
}
并且,在任何控制器类中,都不必再处理ServiceException
了。
另外,在以上类中,可以同时存在多个处理不同异常的方法(允许多个处理的异常之间存在继承关系)!
建议在每个项目中,在统一处理异常的类中,都添加对Throwable
的处理,以保证所有异常都会被处理,粗糙的异常信息不会响应到客户端去!
package cn.tedu.csmall.product.ex.handler;
import cn.tedu.csmall.product.ex.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler
public String handleServiceException(ServiceException e) {
log.debug("处理ServiceException:{}", e.getMessage());
return e.getMessage();
}
@ExceptionHandler
public String handleThrowable(Throwable e) {
log.debug("处理Throwable");
e.printStackTrace();
return "程序运行过程中出现意外错误,请联系系统管理员!";
}
}