我看了一些帖子,试图找到一个使用Spring RestControllers调用服务等方式实现JSON over HTTP后端API的好方法。虽然这是旧帖子,但我们做了以下事情:
我们定义了一个类似于这样的枚举:
public enum Error {
ERROR_0001("0001", "A %s is required for this operation."),
ERROR_0002("0002", "A %s is required."),
ERROR_0003("0003", "Widget number is required."),
ERROR_0004("0004", "Widget number can only be a max 16 characters in length."),
private final String code; private final String description; public static final String ERROR_CODE_PREFIX = "BCV";
Error(String code, String description) {
this.code = code;
this.description = description; }
public String getDescription() {
return description; }
public String getCode() {
return code; }
public String getCodeWithPrefix() {...}
public String getFormattedDescriptionWithCode(@Nullable Object... messageParameters) {...}
public String getFormattedDescription(@Nullable Object... messageParameters) {...}
然后在Spring验证器中我们有:
if (target == null) {
errors.rejectValue(null, ERROR_0001.getCodeWithPrefix(),
ERROR_0001.getFormattedDescriptionWithCode("Something"));
}
而在异常处理中:
@ControllerAdvice(annotations = RestController.class)
@RequestMapping(produces = "application/vnd.error+json")
@Component
public class RestExceptionAdvice {
@ExceptionHandler(Throwable.class)
public ResponseEntity<JsonError> handleUnexpectedException(final Throwable t) {
log.error(t.getMessage(), t);
return new ResponseEntity<>(new JsonError("Unexpected error.", t.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler({
BadArgumentsException.class
})
public ResponseEntity<JsonError> handleBadRequest(final Exception e) {
log.error(e.getMessage(),e);
return new ResponseEntity<>(new JsonError(e.getMessage(), e.getLocalizedMessage()), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler({
MethodArgumentNotValidException.class
})
public ResponseEntity<JsonError> handleValidationBadRequest(final
MethodArgumentNotValidException e) {
log.error(e.getMessage(),e);
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
return new ResponseEntity<>(new JsonError(objectError.getDefaultMessage(), e.getLocalizedMessage()),HttpStatus.BAD_REQUEST);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
private class JsonError {
private String message;
private String details;
}
然后在 UI 中(如 Angular 或其他框架)检查返回的错误是否有“message”字段,并在 Toastr / Error 弹出窗口中显示它。