1、maven依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.17.RELEASE</version>
<relativePath />
</parent>
<dependencies>
<!-- Spring Boot Web 依赖 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Test 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
</dependencies>
SpringBoot的项目已经对有一定的异常处理了,但是对于我们开发者而言可能就不太合适了,因此我们需要对这些异常进行统一的捕获并处理。SpringBoot中有一个ControllerAdvice
的注解,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用ExceptionHandler
注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。
第一步:自定义异常类
自定义一个异常类(注意要继承RuntimeException),属性包含异常信息和异常编码,用于处理我们发生的业务异常。
实例1:
/**
* Describe: 业 务 异 常
* CreateTime: 2019/10/23
* */
public class BusinessException extends RuntimeException {
/**
* 异常消息
* */
protected final String message;
/**
* 业务异常
* */
public BusinessException(String message){
this.message = message;
}
/**
* 异常获取
* */
@Override
public String getMessage() {
return message;
}
}
实力2:
public class BizException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
protected String errorCode;
/**
* 错误信息
*/
protected String errorMsg;
public BizException() {
super();
}
public BizException(BaseErrorInfoInterface errorInfoInterface) {
super(errorInfoInterface.getResultCode());
this.errorCode = errorInfoInterface.getResultCode();
this.errorMsg = errorInfoInterface.getResultMsg();
}
public BizException(BaseErrorInfoInterface errorInfoInterface, Throwable cause) {
super(errorInfoInterface.getResultCode(), cause);
this.errorCode = errorInfoInterface.getResultCode();
this.errorMsg = errorInfoInterface.getResultMsg();
}
public BizException(String errorMsg) {
super(errorMsg);
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg) {
super(errorCode);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public BizException(String errorCode, String errorMsg, Throwable cause) {
super(errorCode, cause);
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
public String getMessage() {
return errorMsg;
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}
第二步:自定义全局异常处理类
注意@RestControllerAdvice、 @ExceptionHandler的用法。
栗子1:
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 不 支 持 的 请 求 类 型
* */
@ExceptionHandler({HttpRequestMethodNotSupportedException.class})
public Result handleException(HttpRequestMethodNotSupportedException e){
log.error(e.getMessage(),e);
return Result.failure("不支持' " + e.getMethod() + "'请求");
}
/**
* 拦 截 未 知 的 运 行 时 异 常
*/
@ExceptionHandler({RuntimeException.class})
public Result notFount(RuntimeException e)
{
log.error("运行时异常:", e);
return Result.failure("运行时异常:" + e.getMessage());
}
/**
* 权 限 异 常 处 理
* */
@ExceptionHandler({AccessDeniedException.class})
public Object access(HttpServletRequest request,AccessDeniedException e){
e.printStackTrace();
if (ServletUtil.isAjax(request))
{
return Result.failure("暂无权限");
} else {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("errorMessage", e.getMessage());
modelAndView.setViewName("error/403");
return modelAndView;
}
}
/**
* 系统异常
*/
@ExceptionHandler(Exception.class)
public Result handleException(Exception e)
{
log.error(e.getMessage(), e);
return Result.failure("服务器错误,请联系管理员");
}
/**
* 业务异常
*/
@ExceptionHandler(BusinessException.class)
public Object businessException(HttpServletRequest request, BusinessException e)
{
log.error(e.getMessage(), e);
if (ServletUtil.isAjax(request))
{
return Result.failure(e.getMessage());
}
else
{
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("errorMessage", e.getMessage());
modelAndView.setViewName("error/500");
return modelAndView;
}
}
}
栗子2:
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 处理自定义的业务异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value = BizException.class)
@ResponseBody
public ResultBody bizExceptionHandler(HttpServletRequest req, BizException e){
logger.error("发生业务异常!原因是:{}",e.getErrorMsg());
return ResultBody.error(e.getErrorCode(),e.getErrorMsg());
}
/**
* 处理空指针的异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =NullPointerException.class)
@ResponseBody
public ResultBody exceptionHandler(HttpServletRequest req, NullPointerException e){
logger.error("发生空指针异常!原因是:",e);
return ResultBody.error(CommonEnum.BODY_NOT_MATCH);
}
/**
* 处理其他异常
* @param req
* @param e
* @return
*/
@ExceptionHandler(value =Exception.class)
@ResponseBody
public ResultBody exceptionHandler(HttpServletRequest req, Exception e){
logger.error("未知异常!原因是:",e);
return ResultBody.error(CommonEnum.INTERNAL_SERVER_ERROR);
}
}
第三部,抛异常
通过 throw new BizException抛出自定义异常
@RestController
@RequestMapping(value = "/api")
public class UserRestController {
@PostMapping("/user")
public boolean insert(@RequestBody User user) {
System.out.println("开始新增...");
//如果姓名为空就手动抛出一个自定义的异常!
if(user.getName()==null){
throw new BizException("-1","用户姓名不能为空!");
}
return true;
}
@PutMapping("/user")
public boolean update(@RequestBody User user) {
System.out.println("开始更新...");
//这里故意造成一个空指针的异常,并且不进行处理
String str=null;
str.equals("111");
return true;
}
@DeleteMapping("/user")
public boolean delete(@RequestBody User user) {
System.out.println("开始删除...");
//这里故意造成一个异常,并且不进行处理
Integer.parseInt("abc123");
return true;
}
@GetMapping("/user")
public List<User> findByUser(User user) {
System.out.println("开始查询...");
List<User> userList =new ArrayList<>();
User user2=new User();
user2.setId(1L);
user2.setName("xuwujing");
user2.setAge(18);
userList.add(user2);
return userList;
}
}
参考文档:gitee.com/toopoo/SpringCloud?_from=gitee_search