dto参数校验及统一异常处理
DTO文件中常用的注解应用案例
SpringBoot参数校验
依赖包
<!-- 在springBoot2.3版本后需要自己引入javax.validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
dto类中的注解
@Data
public class OrderDTO {
/**
* 站点选择;逗号隔开
*/
@NotBlank
private String stations;
/**
* 要素选择;逗号隔开
*/
@NotBlank
private String elements;
/**
* 服务时长
*/
@NotNull
private Integer serveDuration;
/**
* 接口ID
*/
@NotBlank
private String interfaceId;
/**
* 产品ID
*/
@NotBlank
private String dataCode;
}
controller参数中添加@Valid注解
/**
* 创建订单
* @param orderDTO 前端传入的订单参数对象
* @return 结果
*/
@PreAuthorize("hasAuthority('user:order:create')")
@PostMapping("/create")
public Object create(@RequestBody @Validated OrderDTO orderDTO) {
return orderService.createOrder(orderDTO);
}
在全局异常处理类中处理validate异常处理
import cma.sxqxgxw.utils.result.CodeMsg;
import cma.sxqxgxw.utils.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
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.multipart.MaxUploadSizeExceededException;
import javax.validation.UnexpectedTypeException;
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
@ResponseBody
public Result<?> handleException(Exception e) throws Exception {
if (e instanceof AccessDeniedException) {
throw e;
}
if (e instanceof HttpRequestMethodNotSupportedException) {
return Result.error(new CodeMsg(5052, e.getMessage()));
}
if (e instanceof ServiceException) {
return Result.error(new CodeMsg(5052, e.getMessage()));
}
if (e instanceof HttpMessageNotReadableException) {
return Result.error(new CodeMsg(5053, "参数无法识别!请检查参数"));
}
if (e instanceof MissingServletRequestParameterException) {
return Result.error(CodeMsg.CONTROL_ERROR);
}
if (e instanceof UnexpectedTypeException) {
return Result.error(CodeMsg.CONTROL_ERROR);
}
if (e instanceof MaxUploadSizeExceededException) {
return Result.error(new CodeMsg(5054, "文件总大小不能超过300MB"));
}
//方法参数校验异常处理
if (e instanceof MethodArgumentNotValidException) {
return Result.error(CodeMsg.CONTROL_ERROR);
}
if (e instanceof BindException) {
return Result.error(CodeMsg.CONTROL_ERROR);
}
e.printStackTrace();
return Result.error(CodeMsg.SERVER_ERROR);
}
}
自定义返回码
public class CodeMsg {
private int code;
private String msg;
//通用的错误码
public static CodeMsg SUCCESS = new CodeMsg(0, "success");
public static CodeMsg TOKEN_EXPIRED = new CodeMsg(400, "token过期");
public static CodeMsg TOKEN_INVALID = new CodeMsg(401, "token解析异常");
public static CodeMsg USER_NOT_LOGGED_IN = new CodeMsg(402, "未登录,请登录!");
public static CodeMsg SIGNATURE_ERROR = new CodeMsg(506, "签名失败");
public static CodeMsg SERVER_ERROR = new CodeMsg(500, "服务端异常");
public static CodeMsg FILE_ERROR = new CodeMsg(501, "文件不存在");
public static CodeMsg FILE_EXIST = new CodeMsg(5012, "文件已存在");
public static CodeMsg TIME_ERROR = new CodeMsg(502, "时间格式错误,应为 yyyy-MM-dd HH:mm:ss");
public static CodeMsg TIMEMISS_ERROR = new CodeMsg(503, "查询时间缺失,应为 yyyy-MM-dd HH:mm:ss");
public static CodeMsg BIND_ERROR = new CodeMsg(504, "参数绑定异常");
public static CodeMsg CONTROL_ERROR = new CodeMsg(505, "方法参数校验不通过");
public static CodeMsg BINDING_FAILED = new CodeMsg(506, "绑定失败");
public static CodeMsg UNBIND_FAILED = new CodeMsg(507, "解绑失败");
//省略别的自定义错误码
private CodeMsg() {
}
public CodeMsg(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
/**
* 返回带参数的错误码
* @param args
* @return
*/
public CodeMsg fillArgs(Object... args) {
int code = this.code;
String message = String.format(this.msg, args);
return new CodeMsg(code, message);
}
@Override
public String toString() {
return "CodeMsg [code=" + code + ", msg=" + msg + "]";
}
}
封装返回值与返回编码
import com.fasterxml.jackson.annotation.JsonInclude;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import java.util.stream.Collectors;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Result<T> {
private int code;
private String msg="success";
private T data;
/**
* 成功时候的调用
* */
public static <T> Result<T> success() {
Result<T> result = new Result<T>();
result.code = 1;
return result;
}
public static<T> Result<T> success(T data){
return new Result<T>(data);
}
/**
* 失败时候的调用
* */
public static <T> Result<T> error(CodeMsg codeMsg){
return new Result<T>(codeMsg);
}
private Result(T data) {
this.data = data;
}
private Result(int code, String msg) {
this.code = code;
this.msg = msg;
}
private Result() {
}
private Result(CodeMsg codeMsg) {
if(codeMsg != null) {
this.code = codeMsg.getCode();
this.msg = codeMsg.getMsg();
}
}
/**
* BindingResult统一处理
*/
public static Result resolveBindResult(BindingResult bindingResult){
StringBuilder stringBuilder = new StringBuilder();
for (String s : bindingResult.getFieldErrors().stream().map(FieldError::getDefaultMessage).collect(Collectors.toList())) {
stringBuilder.append(",").append(s);
}
return Result.error(new CodeMsg(502,stringBuilder.toString().substring(1)));
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Result [code=" + code + ", msg=" + msg + ", data=" + data + "]";
}
}