【问题标题】:Xml serialization JAXB vs Jackson-dataformat-xml?Xml序列化JAXB与Jackson-dataformat-xml?
【发布时间】:2017-01-11 06:27:42
【问题描述】:

我有一个 XSD,我希望从中支持 JSON 和 XML 数据格式的序列化/反序列化。

我使用xjc 实用程序生成了我的模型类。

到目前为止,我已经使用 Jackson JSON 库处理 JSON 数据。

我无法修改我的 Java 类,因此我配置了 ObjectMapper 与 Mix-In annotations 和其他功能,如 PropertyNamingStrategy(更改字段名称)、SerializationFeature.WRAP_ROOT_VALUE 以通过代码为我的序列化提供配置。

现在我想对 XML 序列化过程做同样的事情。

我已经在线阅读了各种选项:

  1. JAXB
  2. Jackson 库 + Jackson-dataformat-xml.jar
  3. XStream

哪个最适合我的情况(不能用注释编辑我的 POJO,只允许代码配置)??

【问题讨论】:

  • 好奇你最后选择了什么?尽管 jackson 提供了一个更简洁的编程模型 - 它对于 xml 序列化有一个特别讨厌的问题,因为它无法在来自 jaxb 注释模型的序列化 xml 中预先添加默认名称空间名称。这迫使我在一个项目中放弃了这个
  • @redzedi 由于 jackson xml 序列化中的命名空间问题(如您所述),我坚持使用 JAXB。
  • @redzedi:我添加了一个答案,其中包含我的 JAXB 选择的详细信息。虽然 jackson xml 库如果适合您的目的也非常好。

标签: json xml jaxb jackson jackson-dataformat-xml


【解决方案1】:

我的投票是 #2 Jackson 库 + Jackson-dataformat-xml.jar 看看 JSON 和 XML 的代码,这里和那里有点变化是一样的。

主类

  import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
  import com.fasterxml.jackson.annotation.PropertyAccessor;
  import com.fasterxml.jackson.core.JsonProcessingException;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import com.fasterxml.jackson.databind.SerializationFeature;
  import com.fasterxml.jackson.dataformat.xml.XmlMapper;

 public class MainClass {

public static void main(String[] args) throws JsonProcessingException {

    // Serialization: java obj to json--> writeValueAsString
    // DeSerialization: json to java obj--> ReadValue

    XmlMapper mapper1 = new XmlMapper();
    ObjectMapper mapper2 = new ObjectMapper();

    mapper1.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    mapper2.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

    mapper1.enable(SerializationFeature.INDENT_OUTPUT);
    mapper2.enable(SerializationFeature.INDENT_OUTPUT);

    MyPojo mypojo = new MyPojo();
    mypojo.setName("Dhani");
    mypojo.setId("18082013");
    mypojo.setAge(5);

    String jsonStringXML = mapper1.writeValueAsString(mypojo);
    String jsonStringJSON = mapper2.writeValueAsString(mypojo);
    // takes java class with def or customized constructors and creates JSON

    System.out.println("XML is " + "\n" + jsonStringXML + "\n");
    System.out.println("Json is " + "\n" + jsonStringJSON);
}   }

MyPojo.java

   import com.fasterxml.jackson.annotation.JsonIgnore;
   import com.fasterxml.jackson.annotation.JsonProperty;
   import com.fasterxml.jackson.annotation.JsonPropertyOrder;
   import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

  @JsonPropertyOrder({ "name", "age", "id", "note" })
  @JacksonXmlRootElement(namespace = "urn:stackify:jacksonxml", localName = "myPOJO")
   public class MyPojo {

@JsonProperty("_id")
private String id;

private String name;

private int age;

@JsonIgnore
private String note;

public String getNote() {
    return note;
}

public void setNote(String note) {
    this.note = note;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
} }

结果

XML

        <myPOJO xmlns="urn:stackify:jacksonxml">
        <name xmlns="">Dhani</name>
         <age xmlns="">5</age>
         <_id xmlns="">18082013</_id>
         </myPOJO>

Json

     {
      "name" : "Dhani",
       "age" : 5,
       "_id" : "18082013"
         }

【讨论】:

    【解决方案2】:

    我为我的 XML 序列化/反序列化选择了 JAXB,因为我已经有一个 XML 模式,并且想要以 JAXB 作为本机 XML 库的方式提供的 XML。即使 Jackson xml 满足您的需求,它也是一个不错的选择。

    Jackson XML 模块的限制:

    Jackson 中的 XML 模块绝不是为了完全替代 JAXB 而设计的。在 JAXB 和 Jackson 之间,某些结构的工作方式会略有不同,并且无法保证 Jackson 会生成与 JAXB 相同的 XML。

    请注意,与 JSON 不同,最外层对象必须是 bean 类型——它不能是原始类型或包装类型、枚举或集合。这是 XML 工作方式的直接结果——XML 无法表示这样的顶级值。

    默认情况下,Jackson 将始终为集合使用包装器元素,这也与 JAXB 的工作方式不同。这是 Jackson 生成的 XML 与 JAXB 生成的 XML 不兼容的主要方式。当然,可以配置行为,使用 JacksonXmlElementWrapper 注释一个字段或全局 XmlMapper 上的 setDefaultUseWrapper 配置设置。

    Jackson 也不支持使用特定的 XML 模式。 它是为首先编写 Java Bean 而设计的,而不是从预先存在的模式生成 Java 代码。 请注意,这可以通过使用 JAXB 注释支持并使用标准 xjc 生成 bean 在一定程度上解决工具。

    同样,它不支持一些更高级的 XML 工具,例如 XPath 或 XSLT。如果我们需要这种级别的支持,那么我们应该改用功能更全面的 XML 解决方案。

    总结:

    如果您正在寻找一种成熟、灵活的方式来支持和使用 JSON 和 XML 处理相同的数据,Jackson XML 模块是一个可以利用的绝佳库。这不仅是一种可靠的独立方式,而且还具有额外的好处,即能够在很大程度上为 XML 和 JSON 重用相同的配置。

    通常,这必须使用具有完全独立配置的两个不同库来处理。

    最后,除了灵活性和易用性之外,Jackson 团队历来都非常重视性能。鉴于数据的编组和解组是大多数 Web 应用程序的重要组成部分,因此选择正确的库来处理所有这些工作至关重要。再加上 Retrace 等性能监控工具,您可以充分利用应用。

    参考:https://stackify.com/java-xml-jackson/

    【讨论】:

      【解决方案3】:

      我投票支持答案 #2:使用 Jackson-dataformat-xml。我们遇到了类似的情况,发现通过 Jackson 序列化为 XML 比预期的要容易。这是因为XmlMapper 扩展了ObjectMapper,所以我们所有的配置更改(混合、使用JavaTimeModule 等)都可以直接应用于XmlMapper,并且它们就可以正常工作。

      您已经将 Jackson 配置为根据需要输出数据,因此完成了困难的部分。我建议利用您已经投入的精力并使用 Jackson-dataformat-xml。

      【讨论】:

        猜你喜欢
        • 2016-03-02
        • 2015-05-19
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-30
        • 1970-01-01
        • 2019-11-20
        相关资源
        最近更新 更多