XML 使用 jackson 将 POJO 映射到 XML 会产生重复的标签

XML Mapping of POJO to XML using jackson produces duplicate tags

输入样本:

{
  "InventoryDetails" : {
    "Inventory" : {
      "Details" : {
        "Category" : "Fruits",
        "Type" : "Perishable"
      },
      "Properties" : {
        "OptField" : [ {
          "Name" : "Apple",
          "Value" : "Red"
        }, {
          "Name" : "Orange",
          "Value" : "Orange"
        }, {
          "Name" : "Grapes",
          "Value" : "Green"
        }
    ]
      }
    }
  }
}

我正在将 json 映射到 pojo,并尝试使用 xml 映射器将 pojo 转换为 xml。

这个转换是有要求的,不能直接把json转成xml,所以只好硬着头皮做,转[=60=之前有一些转换过程]

但是当我这样做时,我可以看到根元素标签被打印了两次,谁能帮我解决这个问题。

输出

<InventoryDetails>
    <InventoryDetails>
        <Inventory>
            <Details>
                <Category>Fruits</Category>
                <Type>Perishable</Type>
            </Details>
            <Properties>
                <OptField>
                    <Name>Apple</Name>
                    <Value>Red</Value>
                </OptField>
                <OptField>
                    <Name>Orange</Name>
                    <Value>Orange</Value>
                </OptField>
                <OptField>
                    <Name>Grapes</Name>
                    <Value>Green</Value>
                </OptField>
            </Properties>
        </Inventory>
    </InventoryDetails>
</InventoryDetails> 

POJO 1

package com.inventory;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "Inventory"
})
public class InventoryDetails {

    @JsonProperty("Inventory")
    private com.inventory.Inventory Inventory;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The Inventory
     */
    @JsonProperty("Inventory")
    public com.inventory.Inventory getInventory() {
        return Inventory;
    }

    /**
     * 
     * @param Inventory
     *     The Inventory
     */
    @JsonProperty("Inventory")
    public void setInventory(com.inventory.Inventory Inventory) {
        this.Inventory = Inventory;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

POJO 2

package com.inventory;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "Details",
    "Properties"
})
public class Inventory {

    @JsonProperty("Details")
    private com.inventory.Details Details;
    @JsonProperty("Properties")
    private com.inventory.Properties Properties;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The Details
     */
    @JsonProperty("Details")
    public com.inventory.Details getDetails() {
        return Details;
    }

    /**
     * 
     * @param Details
     *     The Details
     */
    @JsonProperty("Details")
    public void setDetails(com.inventory.Details Details) {
        this.Details = Details;
    }

    /**
     * 
     * @return
     *     The Properties
     */
    @JsonProperty("Properties")
    public com.inventory.Properties getProperties() {
        return Properties;
    }

    /**
     * 
     * @param Properties
     *     The Properties
     */
    @JsonProperty("Properties")
    public void setProperties(com.inventory.Properties Properties) {
        this.Properties = Properties;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

POJO 3

package com.inventory;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "Category",
    "Type"
})
public class Details {

    @JsonProperty("Category")
    private String Category;
    @JsonProperty("Type")
    private String Type;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The Category
     */
    @JsonProperty("Category")
    public String getCategory() {
        return Category;
    }

    /**
     * 
     * @param Category
     *     The Category
     */
    @JsonProperty("Category")
    public void setCategory(String Category) {
        this.Category = Category;
    }

    /**
     * 
     * @return
     *     The Type
     */
    @JsonProperty("Type")
    public String getType() {
        return Type;
    }

    /**
     * 
     * @param Type
     *     The Type
     */
    @JsonProperty("Type")
    public void setType(String Type) {
        this.Type = Type;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

POJO 4

package com.inventory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "OptField"
})
public class Properties {

    @JsonProperty("OptField")
    private List<com.inventory.OptField> OptField = new ArrayList<com.inventory.OptField>();
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The OptField
     */
    @JsonProperty("OptField")
    public List<com.inventory.OptField> getOptField() {
        return OptField;
    }

    /**
     * 
     * @param OptField
     *     The OptField
     */
    @JsonProperty("OptField")
    public void setOptField(List<com.inventory.OptField> OptField) {
        this.OptField = OptField;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

POJO 5

package com.inventory;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "Name",
    "Value"
})
public class OptField {

    @JsonProperty("Name")
    private String Name;
    @JsonProperty("Value")
    private String Value;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The Name
     */
    @JsonProperty("Name")
    public String getName() {
        return Name;
    }

    /**
     * 
     * @param Name
     *     The Name
     */
    @JsonProperty("Name")
    public void setName(String Name) {
        this.Name = Name;
    }

    /**
     * 
     * @return
     *     The Value
     */
    @JsonProperty("Value")
    public String getValue() {
        return Value;
    }

    /**
     * 
     * @param Value
     *     The Value
     */
    @JsonProperty("Value")
    public void setValue(String Value) {
        this.Value = Value;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

}

要测试的代码

package com.tester;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.apache.commons.io.IOUtils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.inventory.InventoryDetails;

public class Tester {

    public static void main(String[] args) {
        String jsonStr = "";
        try (InputStream inputStream = new FileInputStream(
                new File("file.json"))) {
            jsonStr = IOUtils.toString(inputStream);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

        // Map to POJO
        ObjectMapper mapper = new ObjectMapper();
        InventoryDetails inventoryDetails = null;
        try {
            inventoryDetails = mapper
                    .readValue(jsonStr, InventoryDetails.class);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Print XML
        ObjectMapper xmlMapper = new XmlMapper();
        String request = "";
        try {
            request = xmlMapper.writeValueAsString(inventoryDetails);
        } catch (JsonProcessingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        System.out.println(request);
    }

}

here 开始,默认使用简单的 class 名称作为根元素。

要解决这个问题,请从输入中移除封闭对象 JSON:

{
"Inventory" : {
  "Details" : {
    "Category" : "Fruits",
    "Type" : "Perishable"
  },
  "Properties" : {
    "OptField" : [ {
      "Name" : "Apple",
      "Value" : "Red"
    }, {
      "Name" : "Orange",
      "Value" : "Orange"
    }, {
      "Name" : "Grapes",
      "Value" : "Green"
    }
    ]
  }
 }
}