如何处理春季启动中各种数据不匹配的杰克逊反序列化错误



我知道这里有一些类似的问题,关于如何解析ENUM,如何解析自定义JSON结构。但在这里,我的问题是当用户提交一些 JSON 与预期不符时,如何提供更好的消息。

这是代码:

@PutMapping
public ResponseEntity updateLimitations(@PathVariable("userId") String userId,
@RequestBody LimitationParams params) {
Limitations limitations = user.getLimitations();
params.getDatasets().forEach(limitations::updateDatasetLimitation);
params.getResources().forEach(limitations::updateResourceLimitation);
userRepository.save(user);
return ResponseEntity.noContent().build();
}

我期望的请求正文是这样的:

{
"datasets": {"public": 10},
"resources": {"cpu": 2}
}

但是当他们提交这样的东西时:

{
"datasets": {"public": "str"}, // <--- a string is given
"resources": {"cpu": 2}
}

响应将在日志中显示如下内容:

400 JSON parse error: Cannot deserialize value of type `java.lang.Integer` from String "invalid": not a valid Integer value; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.lang.Integer` from String "invalid": not a valid Integer value

在 [来源: (PushbackInputStream(; 行: 1, 列: 23] (通过参考链: com.openbayes.api.users.LimitParams["datasets"]->java.util.LinkedHashMap["public"](

但我想要的是一个更人性化的信息。

我试图将ExceptionHandler用于com.fasterxml.jackson.databind.exc.InvalidFormatException但它不起作用。

您可以编写控制器建议来捕获异常并返回相应的错误响应。

以下是 Spring 启动中的控制器建议示例:

@RestControllerAdvice
public class ControllerAdvice {
@ExceptionHandler(InvalidFormatException.class)
public ResponseEntity<ErrorResponse> invalidFormatException(final InvalidFormatException e) {
return error(e, HttpStatus.BAD_REQUEST);
}
private ResponseEntity <ErrorResponse> error(final Exception exception, final HttpStatus httpStatus) {
final String message = Optional.ofNullable(exception.getMessage()).orElse(exception.getClass().getSimpleName());
return new ResponseEntity(new ErrorResponse(message), httpStatus);
}
}
@AllArgsConstructor
@NoArgsConstructor
@Data
public class ErrorResponse {
private String errorMessage;
}

真正的例外是org.springframework.http.converter.HttpMessageNotReadableException。 拦截这个,它就会起作用。

public ResponseEntity<String> handle(HttpMessageNotReadableException e) {
return ResponseEntity.badRequest().body("your own message" + e.getMessage());
}

以下错误处理方法对我有用。

@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity handleAllOtherErrors(HttpMessageNotReadableException formatException) {
String error = formatException.getMessage().toString();
return new ResponseEntity(error, HttpStatus.BAD_REQUEST);

最新更新