如何使用 jackson 序列化 JSON 字符串中缺失的字段
How to make serialize missing fields in JSON String with jackson
我正在读取一个 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;
}
现在这里的 objective 是读取 OnError.alert.isEnabled
但是如果这个字段或整个 onError
部分不可用那么我们必须将它设置为默认值 真
我为此编写的函数是:-
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;
}
这样我就可以通过调用上面的函数找到配置中是否可用的值 -
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)
我正在读取一个 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;
}
现在这里的 objective 是读取 OnError.alert.isEnabled
但是如果这个字段或整个 onError
部分不可用那么我们必须将它设置为默认值 真
我为此编写的函数是:-
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;
}
这样我就可以通过调用上面的函数找到配置中是否可用的值 -
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)