java - Jackson 用对象值反序列化 Json Patch

标签 java json spring json-patch

我在我的 Spring 项目 PATCH 端点中使用 JsonPatch (JSR-374) 和 Apache org.apache.johnzon:johnzon-core:1.2.4 的实现:

@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
    ObjectMapper objectMapper = builder.createXmlMapper(false).build();
    objectMapper.registerModule(new Jdk8Module());
    objectMapper.registerModule(new JSR353Module());
    return objectMapper;
}

Controller

@PatchMapping("/settings")
public ResponseEntity<SettingsResponse> patchSettings(@RequestBody JsonPatch patchDocument, Locale locale) {...}

使用简单原子值的 json 请求

[
  { "op": "replace", "path": "/currency", "value": "EUR" },
  { "op": "test", "path": "/version", "value": 10 }
]

Jackson 正确反序列化了 JsonPatch 实例

但对于复杂值类型(对象):

[
  { "op": "replace", "path": "/currency", "value": {"code": "USD", "label": "US Dollar"} },
  { "op": "test", "path": "/version", "value": 10 }
]

抛出异常

Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of javax.json.JsonPatch (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information at [Source: (PushbackInputStream); line: 1, column: 1]

我认为 JsonPatch(及其 Apache JsonPatchImpl)能够处理复杂类型,因为 JsonValue 提到了 JsonObject 和 ValueType.OBJECT,但我不知道如何指示 Jackson 正确反序列化

预先感谢您的任何建议或帮助!

最佳答案

我通过使用 JSR-364 实现 Json.createPatch 完成了这个过程:

@PatchMapping("/settings")
public ResponseEntity<SettingsResponse> patchDefaultSettingsJsonP3(@RequestBody String patchString, Locale locale) {
    try (JsonReader jsonReader = Json.createReader(new StringReader(patchString))) {
        JsonPatch patch = Json.createPatch(jsonReader.readArray());
        ...
    }
}

编辑: 我通过将转换器注册为 bean 找到了更明智的解决方案。 Spring 然后在内部处理反序列化

@Component
public class JsonPatchHttpMessageConverter extends AbstractHttpMessageConverter<JsonPatch> {

public JsonPatchHttpMessageConverter() {
    super(MediaType.valueOf("application/json-patch+json"), MediaType.APPLICATION_JSON);
}

@Override
protected boolean supports(Class<?> clazz) {
    return JsonPatch.class.isAssignableFrom(clazz);
}

@Override
protected JsonPatch readInternal(Class<? extends JsonPatch> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
    try (JsonReader reader = Json.createReader(inputMessage.getBody())) {
        return Json.createPatch(reader.readArray());
    } catch (Exception e) {
        throw new HttpMessageNotReadableException(e.getMessage(), inputMessage);
    }
}

@Override
protected void writeInternal(JsonPatch jsonPatch, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
    throw new NotImplementedException("The write Json patch is not implemented");
}
}

关于java - Jackson 用对象值反序列化 Json Patch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61115545/

相关文章:

java - JAVA中图片比较

php - API json postman 和 drupal 8

java - 为什么我的 JPA Repository Impl 代码没有被调用?

java - 声明式 Spring 缓存定制

javascript - angularjs ng-将嵌套数组重复到一个唯一列表中

java - spring auth错误没有AuthenticationProvider

java - 不处理 Apache tile 定义中的 EL 表达式

java - HTTP 状态 500 - 无法获取序列名称 : Visitor 的下一个排序 ID

java - 使用队列的生产者/消费者线程

php - 如何仅使用新元素更新 json 文件?