如何使用 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)