我如何在 Java 的 Jackson 库中打印一个对象的名称作为 JSON 的一部分?

How would I print an object's name as part of the JSON in Java's Jackson library?

我正在尝试确定如何使用 Java 的 Jackson 库打印出如下所示的 JSON:

{
    "status": {
        {
          "busStatus" : {
            "status" : null,
            "transactions" : "0",
            "retries" : "0",
            "failures" : "0"
          }
        }
    }
}

我已经完成了 95%,但是最外面的对象目前还没有被打印出来。这是我目前得到的输出:

{
  "busStatus" : {
    "status" : null,
    "transactions" : "0",
    "retries" : "0",
    "failures" : "0"
  }
}

我有一个 Java class 看起来像这样:

public class DataClass {

    public StatusData status = new StatusData();
    public StatusConfig config = new StatusConfig();
    

    public class StatusData {
        public SerialStatus busStatus = new SerialStatus();
    }
    
    public class StatusConfig {
        
    }

    public class SerialStatus {
        public String status = null;
        public String transactions = "0";
        public String retries = "0";
        public String failures = "0";
    }
}

我正在使用以下代码将此 class 打印到 json:

private DataClass internalData;
ObjectMapper mapper = new ObjectMapper();
status = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(internalData.status);

有没有一种方法可以配置 Jackson 以打印出其序列化到 JSON 中的对象的名称?

为了达到你想要的效果,你需要打印 DataClass 而不是 StatusData。如下所示:

private DataClass internalData = <initialize>;
ObjectMapper mapper = new ObjectMapper();
String data = 
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(internalData);

您可以使用 Jackson Filter 来控制序列化过程,我认为它应该适用于您的用例,至少有一种方法可以做到。

使用过滤器注释,然后为您的 class 创建两个不同的过滤器,您可以在其中定义要跳过的字段,并相应地与 ObjectMapper 一起使用它来转换整个 internalData 对象,因此,当您需要跳过状态时,使用一个过滤器,当您需要跳过配置时,将另一个过滤器与映射器相关联,同时始终序列化父对象。哪个应该给你你想要的结构。

        @JsonFilter("filter_serializer")
        class User {
            public String v1;
            public String v2;
        }

        String[] fieldsToSkip = new String[] { "v1" };

        ObjectMapper mapper = new ObjectMapper();

        final SimpleFilterProvider filter = new SimpleFilterProvider();
        filter.addFilter("filter_serializer",
                         SimpleBeanPropertyFilter.serializeAllExcept(fieldsToSkip));


        User dtoObject = new User();
        dtoObject.v1 = "v1";
        dtoObject.v2 = "v2";
        String jsonStr =  mapper.writer(filter).writeValueAsString(dtoObject);
    

我能够找到我正在寻找的解决方案,from this website

我摆脱了 DataClass,现在只有一个 StatusData 和一个 StatusConfig class。我在下面包含了 StatusData class 的外观:

@JsonRootName(value = "status")
public class StatusData {
    String status;
    String transactions;
    // so on
}

为了解析 class,我需要在上面添加 JsonRootName 注释,并在映射器上启用一个功能,如下所示:

private DataClass internalData;
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE); // don't forget this!
statusText = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(statusObject);

另外,如果您想将 JSON 反序列化为像 StatusData 这样的 class,请执行以下操作:

mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
statusObject = mapper.readValue(statusText, StatusData.class);