配置之后当我们进行validate等相关操作时,我们就不再进行返回boolean,然后走不同的分支,在异常情况,可以直接抛出自定义异常,实现代码终止,并给前端返回异常信息.
1.自定义异常类.
/**
* 自定义业务异常
*/
public class CustomException extends RuntimeException{
public CustomException(String message){
super(message);
}
}
2.通用接口返回格式
package com.example.aibinghaosi.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class JsonData{
/**
* 状态码 正数 表示成功,0表示处理中,负数 表示失败
*/
private Integer code;
/**
* 数据
*/
private Object data;
/**
* 描述
*/
private String msg;
/**
* 通用成功状态
* @return 成功的状态
*/
public static JsonData buildSuccess() {
return new JsonData(1, true, "操作成功");
}
/**
* 通用成功状态
* @return 成功的状态
*/
public static JsonData buildSuccess(Object data) {
return new JsonData(1, data, "操作成功");
}
/**
* 失败
* @param msg 失败信息
*/
public static JsonData buildError(String msg) {
return new JsonData(-1, null, msg);
}
/**
* 失败
* @param msg 失败信息
* @param code 失败状态码
*/
public static JsonData buildError(String msg, Integer code) {
if(code>=0){
System.out.println("失败的状态码必须小于0");
return JsonData.buildError(msg);
}
return new JsonData(code, null, msg);
}
}
3.全局异常捕获类
package com.example.aibinghaosi.config;
import com.example.aibinghaosi.common.CustomException;
import com.example.aibinghaosi.common.JsonData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
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.RestController;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* 全局异常处理
* 可以针对不同的异常使用不同的处理方式.
*/
// 设置需要被捕获异常的类:添加了 RestController 或 Controller 的注解的controller类
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
/**
* 异常处理方法
*
* @return 返回给前端的信息
*/
// 指定捕获异常类型(SQL异常)
@ExceptionHandler({SQLIntegrityConstraintViolationException.class, DuplicateKeyException.class})
public JsonData execeptionHandler1(SQLIntegrityConstraintViolationException ex) {
log.info("发生了唯一值重复异常:{}", ex);
// 判断是否违反了唯一约束
if (ex.getMessage().contains("Duplicate entry")) {
String[] strArr = ex.getMessage().split(" ");
String msg = strArr[2] + "已存在!";
return JsonData.buildError(msg);
}
return JsonData.buildError("未知错误!");
}
/**
* 捕获字符串转成Long失败的异常
*/
@ExceptionHandler({MethodArgumentTypeMismatchException.class})
public JsonData execeptionHandler2(MethodArgumentTypeMismatchException ex) {
log.info("发生了字符串转换成Long异常:{}", ex.getMessage());
log.info("发生了字符串转换成Long异常,完整异常信息-------------------------:{}", ex);
if (ex.getMessage().contains("Failed to convert value of type 'java.lang.String' to required type 'java.lang.Long'")) {
String[] strArr = ex.getMessage().split("For input string:");
String msg = "id:" + strArr[1] + "长度超限";
return JsonData.buildError(msg);
}
return JsonData.buildError("未知错误!");
}
/**
* 捕获用户自定义异常
*/
@ExceptionHandler({CustomException.class})
public JsonData execeptionHandler3(CustomException ex) {
return JsonData.buildError(ex.getMessage());
}
/**
* 异常处理方法
*
* @return 返回给前端的信息
*/
// 指定捕获异常类型(SQL异常)
@ExceptionHandler(Exception.class)
public JsonData execeptionHandler999(Exception ex) {
log.info("发生了异常:{}", ex);
return JsonData.buildError("异常:" + ex.getMessage());
}
}
4.使用案例.
@Data
@AllArgsConstructor
@Slf4j
public class ProxyAdd {
UserService userService;
UserStudiesService userStudiesService;
/**
* 新增用户
*
* @param registerUserDto
* @return 用户id
*/
public Long execute(RegisterUserDto registerUserDto) {
this.validateDto(registerUserDto);
this.validateUserExist(registerUserDto);
UserEntity userEntity = new UserEntity();
userEntity.setUsername(registerUserDto.getPhone());
userEntity.setPhone(registerUserDto.getPhone());
userEntity.setPassword(registerUserDto.getPassword());
userService.save(userEntity);
userStudiesService.addDefaultUserStudiesByUserId(userEntity.getId());
return userEntity.getId();
}
/**
* 校验dto是否可用
*
* @param registerUserDto
*/
private void validateDto(RegisterUserDto registerUserDto) {
//-----------------------------------使用自定义异常类------------------------------------
if (registerUserDto.getPhone() == "") throw new CustomException("手机号不能为空");
if (registerUserDto.getPassword() == "") throw new CustomException("密码不能为空");
if (registerUserDto.getCaptcha() == "") throw new CustomException("验证码不能为空");
//-----------------------------------使用自定义异常类------------------------------------
}
/**
* 校验用户是否存在
*
* @param registerUserDto
*/
private void validateUserExist(RegisterUserDto registerUserDto) {
LambdaQueryWrapper<UserEntity> lqw = new LambdaQueryWrapper();
lqw.eq(UserEntity::getPhone, registerUserDto.getPhone());
lqw.or().eq(UserEntity::getPhone, registerUserDto.getPhone());
int count = userService.count(lqw);
if(count>0)throw new CustomException("当前手机号已注册,请直接登录");
}
}