场景
Java Bean Validation主要用于对请求参数的简单检查,如最值,字符串判空等简单约束。
使用
Maven
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Java Bean
@NotEmpty(message = "字符串不能为空")
private String eTag;
@Min(value = 1, message = "最小值为1")
private int partNumber;
Controller
@PostMapping("/uploadMultipartFile")
public ResponseEntity<?> uploadMultipartFile(@Valid UploadFileReq req){
}
使用@Valid
注解,即可以对请求参数Java Bean中的属性进行前端请求约束。
RestControllerAdvice
到这里基本上就解决了spring-boot-starter-validation
的使用问题,如果想要自定义规范异常情况下返回的参数,还需要做如下处理:
@Slf4j
@RestControllerAdvice
public class GlobalExceptionTranslator {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity handleError(MethodArgumentNotValidException e) {
log.warn("Method Argument Not Valid", e);
BindingResult result = e.getBindingResult();
FieldError error = result.getFieldError();
String message = null;
if (error != null) {
message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
}
return ResponseEntity.badRequest()
.body(BaseResponse.builder().code(ResultCode.FAILURE).message(message).build());
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity handleError(ConstraintViolationException e) {
log.warn("Constraint Violation", e);
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
ConstraintViolation<?> violation = violations.iterator().next();
String path = ((PathImpl) violation.getPropertyPath()).getLeafNode().getName();
String message = String.format("%s:%s", path, violation.getMessage());
return ResponseEntity.badRequest()
.body(BaseResponse.builder().code(ResultCode.FAILURE).message(message).build());
}
}
这里主要就是拦截异常处理的过程,将Spring异常报错转成自己定义的DTO类
自定义DTO
BaseResponse.java
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BaseResponse {
private String message;
@Builder.Default
private ResultCode code = ResultCode.SUCCESS;
public boolean isSuccess() {
return code == ResultCode.SUCCESS;
}
}
ResultCode.java
@Getter
@AllArgsConstructor
public enum ResultCode {
SUCCESS(HttpServletResponse.SC_OK, "Operation is Successful"),
FAILURE(HttpServletResponse.SC_BAD_REQUEST, "Biz Exception"),
UN_AUTHORIZED(HttpServletResponse.SC_UNAUTHORIZED, "Request Unauthorized"),
NOT_FOUND(HttpServletResponse.SC_NOT_FOUND, "404 Not Found"),
MSG_NOT_READABLE(HttpServletResponse.SC_BAD_REQUEST, "Message Can't be Read"),
METHOD_NOT_SUPPORTED(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Method Not Supported"),
MEDIA_TYPE_NOT_SUPPORTED(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE, "Media Type Not Supported"),
REQ_REJECT(HttpServletResponse.SC_FORBIDDEN, "Request Rejected"),
INTERNAL_SERVER_ERROR(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Internal Server Error"),
PARAM_MISS(HttpServletResponse.SC_BAD_REQUEST, "Missing Required Parameter"),
PARAM_TYPE_ERROR(HttpServletResponse.SC_BAD_REQUEST, "Parameter Type Mismatch"),
PARAM_BIND_ERROR(HttpServletResponse.SC_BAD_REQUEST, "Parameter Binding Error"),
PARAM_VALID_ERROR(HttpServletResponse.SC_BAD_REQUEST, "Parameter Validation Error");
final int code;
final String msg;
}