前言
我们都知道一般在项目中,前后端交互时,前端访问后端接口,后端接口出现错误时,一般都会返回500的状态码给前端,前端看见一堆500错误,这样体验就会很不好,此时如果我们后端用异常处理一下这些错误,让他出错时返回200状态码,再给一些错误提示,这样体验感就会好很多。小白程序员博主最近刚学了一种处理方法,废话不多说,我们来看具体如何处理?
1.自定义统一处理业务的异常类
首先自定义一个总体的业务异常类让他继承RuntimeException(运行时异常类),并且在类中,编写两个构造法方,一个有参一个无参,有参法方带一个String的参数,目的是用来传异常消息(也就是错误提示之类的),
/**
* 业务异常类
*/
public class BaseException extends RuntimeException {
public BaseException() {
}
public BaseException(String msg) {
super(msg);
}
}
2.定以具体的业务异常继承业务类异常
如密码错误异常:
/**
* 密码错误异常
*/
public class PasswordErrorException extends BaseException {
public PasswordErrorException() {
}
public PasswordErrorException(String msg) {
super(msg);
}
}
3.在业务代码中使用,在可能出现错误的业务代码中使用,如员工登录法方,如用户名不存在就会发生异常,此时我们可以用throw new 自定义的异常类(消息常量类.常量)处理异常。
public Employee login(EmployeeLoginDTO employeeLoginDTO) {
Employee employee = employeeMapper.selectByUserName(employeeLoginDTO.getUsername());
if(employee == null){
//用户名不存在
throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
}
if(employee.getStatus() == StatusConstant.DISABLE){
//账号被锁定
throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED);
}
//对前端传递过来的明文密码进行md5加密处理
String pwd = DigestUtils.md5DigestAsHex(employeeLoginDTO.getPassword().getBytes());
if(!pwd.equals(employee.getPassword())){
//密码输入错误
throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
}
return employee;
}
4.结合AOP切面编程处理异常
首先,定义一个全局异常处理类任然让他继续我们自定义的业务异常类,然后,在类上加@RestControllerAdvice注解,作用是会在所有注解了@RequestMapping的控制器的方法上起作用,最后,再在这个全局异常处理类中定义需要被处理的异常类的法方,用@ExceptionHandler注解标注。
@RestControllerAdvice //@RestControllerAdvice注解将作用在所有注解了@RequestMapping的控制器的方法上
@Slf4j
public class GlobalExceptionHandler extends BaseException {
/**
* * 捕获业务异常
* * @param ex
* * @return
* */
@ExceptionHandler
public R<String> exceptionHandler(BaseException ex){
log.error("捕获到业务异常:"+ex.getMessage());
return R.error(ex.getMessage());
}
/**
* * 捕获SQL异常
* * @param ex
* * @return
* */
@ExceptionHandler
public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
log.error("捕获到业务异常:"+ex.getMessage());
if (ex.getMessage().contains("Duplicate entry")){
String username = ex.getMessage().split(" ")[2]; //从异常消息中提取重复的用户名
return R.error(username+"账号以存在");
}
return R.error(MessageConstant.UNKNOWN_ERROR);
}
}
这里是处理了一个SQL重复字段的异常,如果要处理其他的异常,可在这个类中扩展方法,异常写的越清晰,客户体验感就会越好。
感谢阅读!