Java中的Jackson JSON序列化-将k/v对写入根目录,而不是嵌套在属性名中

Java中的Jackson JSON序列化-将k/v对写入根目录,而不是嵌套在属性名中,java,json,serialization,jackson,Java,Json,Serialization,Jackson,我需要按照以下基本格式编写一个JSON字符串: { "xmlns": { "nskey1" : "nsurl1", "nskey2" : "nsurl2" }, "datakey1": "datavalue1", "datakey2": "datavalue2" } 我使用下面的类来表示数据,这个类的一个实例是用Jackson ObjectMapper序列化的 public class PayloadData { publ

我需要按照以下基本格式编写一个JSON字符串:

{ 
    "xmlns": {
       "nskey1" : "nsurl1",
       "nskey2" : "nsurl2"
    },

    "datakey1": "datavalue1",
    "datakey2": "datavalue2"
}
我使用下面的类来表示数据,这个类的一个实例是用Jackson ObjectMapper序列化的

public class PayloadData {
    public Map<String, String> payloadData = new TreeMap<String, String>();

    @JsonProperty("xmlns")
    public Map<NamespaceEnum, String> namespaces = new TreeMap<NamespaceEnum, String>();

    @JsonAnyGetter
    public Map<String, String> getPayloadData() {
        return payloadData;
    }
}
基于命名约定,这是有意义的,但我正在寻找一种方法,将payloadData映射放置在JSON的根上下文中,而不使用包含属性标识符和嵌套的副本。我尝试了很多不同形式的注释;我已尝试禁用ObjectMapper wrap\u root\u值序列化功能;我真的觉得我什么都试过了。所以,在我把电脑扔出窗外之前,我需要第二双(甚至更多)眼睛来帮助我指出那些显而易见的东西

提前感谢您的关注和建议


编辑:更新了我现在看到的实际输出JSON。正在复制数据,我想删除具有嵌套属性的副本。

您可以将json数据解析为
HashMap
而不是类对象:

public HashMap<String, Object> testJackson(String data) throws IOException {        
    JsonFactory factory = new JsonFactory(); 
    ObjectMapper mapper = new ObjectMapper(factory); 
    TypeReference<HashMap<String,Object>> typeRef 
            = new TypeReference<HashMap<String,Object>>() {};

    HashMap<String,Object> o = mapper.readValue(data, typeRef); 
    return o
}  

问题是您为
PayloadData
公开了两个访问器:public属性和getter,因此它被序列化了两次。如果可能的话,我建议将数据类重新构造为不可变的。例如:

public class PayloadData {
    private final Map<String, String> payloadData;
    private final Map<NamespaceEnum, String> namespaces;

    @JsonCreator
    public PayloadData(@JsonProperty("xmlns") Map<NamespaceEnum, String> namespaces,
                       @JsonProperty("payloadData") Map<String, String> payloadData) {
        this.namespaces = namespaces;
        this.payloadData = payloadData;
    }

    @JsonAnyGetter
    public Map<String, String> getPayloadData() {
        return payloadData;
    }

    @JsonProperty("xmlns")
    public Map<NamespaceEnum, String> getNamespaces() {
        return namespaces;
    }
}
公共类PayloadData{
私人最终地图付费数据;
私有最终映射名称空间;
@JsonCreator
公共PayloadData(@JsonProperty(“xmlns”)映射名称空间,
@JsonProperty(“payloadData”)地图(payloadData){
this.namespaces=名称空间;
this.payloadData=payloadData;
}
@JsonAnyGetter
公共地图getPayloadData(){
返回有效载荷数据;
}
@JsonProperty(“xmlns”)
公共映射getNamespaces(){
返回名称空间;
}
}

这将为您提供所需的输出,而无需对ObjectMapper进行任何配置。

这将用于读取数据。在本例中,我将映射转换为JSON,而不是将JSON解析为映射。如果您将数据解析为
HashMap
,也可以轻松地将其解析为
JSON
。谢谢;这确实有效。我应该说,我正在使用它作为包装类-这两个字段在生命周期中被追加,结果被序列化。不过我可以用这个。关于双重访问的提示让我走上了正确的道路。
public String getJsonFromMap(HashMap<String, Object> data) {
    return new ObjectMapper().writeValueAsString(data);
}
public class PayloadData {
    private final Map<String, String> payloadData;
    private final Map<NamespaceEnum, String> namespaces;

    @JsonCreator
    public PayloadData(@JsonProperty("xmlns") Map<NamespaceEnum, String> namespaces,
                       @JsonProperty("payloadData") Map<String, String> payloadData) {
        this.namespaces = namespaces;
        this.payloadData = payloadData;
    }

    @JsonAnyGetter
    public Map<String, String> getPayloadData() {
        return payloadData;
    }

    @JsonProperty("xmlns")
    public Map<NamespaceEnum, String> getNamespaces() {
        return namespaces;
    }
}