我有 2 個要區分的物件。為此,我Jackson ObjectMapper在 spring-boot 版本 2.1.3 中使用將它們反序列化為字串,將它們作為樹讀取(轉換為JsonNode),然后對它們進行比較以創建JsonPatch物件。我注意到的是,在現有物件的 JsonNode 中,所有具有null值的欄位都被跳過,就像只有null值欄位的物件一樣。消費者(spring-boot 版本 2.6.7)和服務提供者(spring-boot-2.1.3)的ObjectMapper行為似乎不同。樣本,在樹內:
"_optionalAttrs":{"styles":{"99_0002_4_24_002":{"hineck":null,"choices":{"99_0002_4_24_002_001":{"color":null}}},"99_0002_4_24_001":{"hineck":null,"choices":null}}.
對比
"_optionalAttrs":{"styles":{"99_0002_4_24_002":{"choices":{"99_0002_4_24_002_001":{}}},"99_0002_4_24_001":{}}
我猜這就是生成的 JsonPatch 操作不正確的原因:
op: copy; from: "/_optionalAttrs/styles/99_0002_4_24_001/hineck"; path: "/_optionalAttrs/clientAttributes/channel"
我最終得到了這個錯誤 - 目標 JSON 檔案中沒有這樣的路徑。有沒有辦法確保兩者保持一致?如果您認為還有其他問題,請告訴我。消費者代碼是我們可以更改的,但服務提供者代碼不屬于我們所有。我正在使用json-patch-1.12和jdk 11。
uj5u.com熱心網友回復:
默認情況下,ObjectMapper將保留null值,但您可以使用以下設定跳過它們:
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)
uj5u.com熱心網友回復:
我沒有好的解決方案,但總比沒有好您可以使用fieldAndValueMap方法將物件映射到 Map<String, String> 并進行比較
public Map<String, String> fieldAndValueMap(Class<?> type, Object obj) throws ReflectiveOperationException {
Map<String, String> result = new HashMap<>();
for (Field field : type.getDeclaredFields()) {
field.setAccessible(true);
if (isWrapperType(field.getType())) {
String value = nonNull(field.get(obj)) ? field.get(obj).toString() : "null";
result.put(type.getSimpleName() "." field.getName(), value);
} else {
String getMethod = "get" Character.toUpperCase(field.getName().charAt(0)) field.getName().substring(1);
Method method = type.getMethod(getMethod);
Object subObj = method.invoke(obj);
if (nonNull(subObj)) {
result.putAll(fieldAndValueMap(field.getType(), subObj));
}
}
}
return result;
}
public boolean isWrapperType(Class<?> type) {
return getWrapperTypes().contains(type);
}
private Set<Class<?>> getWrapperTypes() {
Set<Class<?>> ret = new HashSet<>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(String.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(Void.class);
ret.add(BigDecimal.class);
ret.add(LocalDate.class);
ret.add(LocalDateTime.class);
ret.add(LocalTime.class);
ret.add(Date.class);
return ret;
}
將物件作為欄位和值的映射:fieldAndValueMap(firstObject.getClass(), firstObject)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/477435.html
下一篇:在JUnit5中,為什么postMethod會拋出TransactionSystemException而不是回傳帶有錯誤請求的ResponseEntity?
