定义统一的返回值格式
ResultCode
@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;
}
BaseResponse
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BaseResponse {
private String message;
@Builder.Default
private ResultCode code = ResultCode.SUCCESS;
public boolean isSuccess() {
return code == ResultCode.SUCCESS;
}
}
定义一个异常处理器
GlobalExceptionTranslator
@Slf4j
@RestControllerAdvice
public class GlobalExceptionTranslator {
@ExceptionHandler(MissingServletRequestParameterException.class)
public BaseResponse handleError(MissingServletRequestParameterException e) {
log.warn("Missing Request Parameter", e);
String message = String.format("Missing Request Parameter: %s", e.getParameterName());
return BaseResponse
.builder()
.code(ResultCode.PARAM_MISS)
.message(message)
.build();
}
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public BaseResponse handleError(MethodArgumentTypeMismatchException e) {
log.warn("Method Argument Type Mismatch", e);
String message = String.format("Method Argument Type Mismatch: %s", e.getName());
return BaseResponse
.builder()
.code(ResultCode.PARAM_TYPE_ERROR)
.message(message)
.build();
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public BaseResponse handleError(MethodArgumentNotValidException e) {
log.warn("Method Argument Not Valid", e);
BindingResult result = e.getBindingResult();
FieldError error = result.getFieldError();
String message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
return BaseResponse
.builder()
.code(ResultCode.PARAM_VALID_ERROR)
.message(message)
.build();
}
@ExceptionHandler(BindException.class)
public BaseResponse handleError(BindException e) {
log.warn("Bind Exception", e);
FieldError error = e.getFieldError();
String message = String.format("%s:%s", error.getField(), error.getDefaultMessage());
return BaseResponse
.builder()
.code(ResultCode.PARAM_BIND_ERROR)
.message(message)
.build();
}
@ExceptionHandler(ConstraintViolationException.class)
public BaseResponse 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 BaseResponse
.builder()
.code(ResultCode.PARAM_VALID_ERROR)
.message(message)
.build();
}
@ExceptionHandler(NoHandlerFoundException.class)
public BaseResponse handleError(NoHandlerFoundException e) {
log.error("404 Not Found", e);
return BaseResponse
.builder()
.code(ResultCode.NOT_FOUND)
.message(e.getMessage())
.build();
}
@ExceptionHandler(HttpMessageNotReadableException.class)
public BaseResponse handleError(HttpMessageNotReadableException e) {
log.error("Message Not Readable", e);
return BaseResponse
.builder()
.code(ResultCode.MSG_NOT_READABLE)
.message(e.getMessage())
.build();
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public BaseResponse handleError(HttpRequestMethodNotSupportedException e) {
log.error("Request Method Not Supported", e);
return BaseResponse
.builder()
.code(ResultCode.METHOD_NOT_SUPPORTED)
.message(e.getMessage())
.build();
}
@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
public BaseResponse handleError(HttpMediaTypeNotSupportedException e) {
log.error("Media Type Not Supported", e);
return BaseResponse
.builder()
.code(ResultCode.MEDIA_TYPE_NOT_SUPPORTED)
.message(e.getMessage())
.build();
}
@ExceptionHandler(Throwable.class)
public BaseResponse handleError(Throwable e) {
log.error("Internal Server Error", e);
return BaseResponse
.builder()
.code(ResultCode.INTERNAL_SERVER_ERROR)
.message(e.getMessage())
.build();
}
}
此时请求任意接口,如果发生异常,我们将会看到类似如下格式的响应信息
{
"message": "phoneNumber:Invalid phone number",
"code": "PARAM_VALID_ERROR",
"success": false
}