java - 如何使用杰克逊序列化 JSON 字符串中的缺失字段
问题描述
我正在阅读一个 JSON 字符串,其中每个字段都是可选的,我需要从配置中获取值或将其设置为默认值。
说我的 JSON 是 -
{
"action": {
"onWarning":{
"alert":{
"isEnabled": true,
"name": "DVS.sd_service.data-validation.bigdata.warning"
}
},
"onError":{
"alert":{
"isEnabled": false,
"name": "DVS.sd_service.data-validation.bigdata.error"
}
}
}
}
我读取这个 JSON 的代码是 -
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.registerModule(new Jdk8Module());
JobConfig jobConfig = mapper.readValue(contentJson, JobConfig.class);
下面是我的包装类 -
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class JobConfig {
public Optional<AlertConfig> action;
}
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class AlertWrapper {
public Optional<Alert> alert;
}
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class AlertConfig {
public Optional<AlertWrapper> onSuccess;
public Optional<AlertWrapper> onWarning;
public Optional<AlertWrapper> onError;
}
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Alert{
public Optional<Boolean> isEnabled;
public Optional<String> name;
}
现在的目标是阅读,OnError.alert.isEnabled
但是如果此字段或整个onError
部分不可用,那么我们必须将其设置为默认值True
我为此编写的功能是:-
private Optional<Boolean> getErrorIsEnabled(JobConfig jobConfig ) {
Optional<Boolean> isEnabled = Optional.empty();
if(jobConfig.action.isPresent()) {
if(jobConfig.action.get().onError.isPresent()){
if(jobConfig.action.get().onError.get().alert.isPresent()) {
if(jobConfig.action.get().onError.get().alert.get().isEnabled.isPresent()){
isEnabled= jobConfig.action.get().onError.get().alert.get().isEnabled;
}
}
}
}
return isEnabled;
}
通过这种方式,我可以通过调用上述函数来查找 vale 在配置中是否可用 -
getErrorIsEnabled(jobConfig).orElse(true)
问题是(调用上述函数)这可行,但看起来太难看,无法通过调用函数继续检查每个级别的字段是否可用isPresent()
。
用户可以完全跳过OnError
部分,或action
部分,或只是alert
部分,或alert.isEnabled
部分。必须有更好的方法来实现这一点!对建议或改进持开放态度,或者一起尝试不同的方法。
解决方案
您应该做的是为字段创建默认值,例如
private Optional<Boolean> isEnabled = Optional.empty();
private Optional<String> name = Optional.empty();
public Alert(Optional<Boolean> isEnabled , Optional<String> name){
this.isEnabled=isEnabled;
this.name=name;
}
对于每个这样的对象 -
private final Alert alertDetail = new Alert(Optional.empty(), Optional.empty());
private final AlertWrapper alertWrapper = new AlertWrapper(alertDetail);
private AlertWrapper onSuccess = alertWrapper;
private AlertWrapper onWarning = alertWrapper;
private AlertWrapper onError = alertWrapper;
您将必须创建构造函数,因此您必须将您的 lombok 更改为@NoArgsConstructor
也使用@Getter @Setter
,这样您就可以调用您的对象,如下所示 -
jobConfig.getAction().getOnWarning().getAlert().getIsEnabled().orElse(true)
推荐阅读
- c# - 将一个数字的符号赋予另一个数字?
- c++ - C++:类型别名中的递归依赖
- save - 使用 QB64 将值保存在 .txt 文档中
- pytorch - Pyro 更改 AutodiagonalNormal 设置
- google-maps - 尝试添加平台 iOS 时出错 googlemaps
- javascript - 如何使用 forEach 方法准确记录我需要的内容
- sql - 了解 where 子句与 join
- watchkit - 是否有 API 可以检查用户的 Apple Watch 上是否启用了密码?
- php - 如何配置可视化学习代码用docker识别php?
- java - 如何在没有 WSConnection 的情况下设置客户端信息