1、前言
我们在使用springboot开发接口提供给网站的时候,由于我们有一些错误,需要自己自定义,所以我们需要在springboot中实现全局异常处理,设置自定义异常
2、springboot实现全局异常处理,自定义异常
首先:我们先创建一个包(Exception)专门用于处理异常的。
其次:我们创建一个BaseException这个类去继承自RuntimeException 因为RuntimeException是继承于Exception(总异常类)的子类
BaseException:创建有参构造,super执行父类方法
package com.recordnetwork.Exception;
public class BaseException extends RuntimeException{
public BaseException( String msg) {
super(msg);
}
}
然后我们再创建全局异常处理器GlobalExceptionHandle并且在这个类并添加@RestControllerAdvice注解,当运行中出发了某个异常,他就会调到这里调用这个异常并返回出去
这里主要定义的就是内部异常,只要捕获到了异常就会执行,比如sql异常,或文件上传太大异常,都可以捕获,并返回出去
package com.recordnetwork.Exception;
import com.recordnetwork.common.Constants;
import com.recordnetwork.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.regex.Pattern;
/**
* 全局异常处理器
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandle {
@ExceptionHandler
public Result exceptionHandler(BaseException ex) {
log.error("异常信息:{}", ex.getMessage());
return Result.error(ex.getMessage());
}
// 处理sql异常 主键重复
@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) {
// 设置了唯一字段,用户账号只能唯一,用户已被注册
// Duplicate entry 'admin' for key 'user.username_unique'
String message = ex.getMessage();
String Phone = "";
// 判断是否包含Duplicate entry这两个字段
if (message.contains("Duplicate entry")) {
// 代表发生了重复的键值对,用空格分隔得到重复的键值对的名称
String[] str = message.split(" ");
message = str[2].replace("'", "");
if (Pattern.matches("\\d+", message)) {
return Result.error("该手机号:" + message + " " + Constants.PHONE_EXIST.getValue());
}
return Result.error("该用户:" + message + " " + Constants.ALREADY_EXIST.getValue());
} else {
return Result.error(Constants.UNKNOWN_ERROR.getValue());
}
}
// 处理sql异常 文件太大
@ExceptionHandler
public Result exceptionHandler(FileSizeLimitExceededException ex) {
log.info("文件太大异常:{}",ex.getMessage());
return Result.error(Constants.FILE_SO_BIG.getValue());
}
}
接着我们可以创建自定义异常类,
例如:用户名和密码不匹配的异常类userNamePwdException 我们只需要去继承我们创建的BaseException异常类,然后去super执行父类的有参构造,并设置自定义内容就可以
package com.recordnetwork.Exception.Son;
import com.recordnetwork.Exception.BaseException;
/**
* 异常类,标识用户名和密码错误
*/
public class userNamePwdException extends BaseException {
public userNamePwdException(String msg) {
super(msg);
}
}
例如在这个方法中:可能会出现用户名和密码不匹配,就会导致查不到数据,而user就会为null就会抛出方法,而这个方法就是我们自定义的用户名或密码不匹配的异常类。
最终返回到前端响应异常
public UserLoginVO Login(UserDTOLogin userDTOLogin) {
UserLoginVO userInfo = null;
User user = userMapper.userLogin(userDTOLogin);
// 用户名或密码错误
if (user == null) {
throw new userNamePwdException("用户名或密码错误");
}
//...其他内容
return userInfo;
}
类目结构如下: