Java中的XML序列化?[关闭]


104

.NET的XML序列化的Java模拟是什么?


6
啊,辉煌的旧时光像SO这样的单线问题受到欢迎。好有用 没有所有的“您尝试了什么?” /“提供详细信息”,废话的人们今天喜欢阅读。
GOTO

Answers:


81

2008解答 现在的“官方” Java API是JAXB-XML绑定的Java API。请参见Oracle教程。参考实现位于http://jaxb.java.net/

2018更新 注意,Java EE和CORBA模块在JDK9中的SE中已弃用,并将在JDK11中从SE中删除。因此,要使用JAXB,要么需要将其放置在您的现有企业级环境中(例如,由应用服务器捆绑),要么需要手动将其引入。


2
是的,JAXB绝对是最佳选择!
ivan_ivanovich_ivanoff 2009年

1
自Java 10起,JAXB已从标准Ja​​va发行版中删除,这使其现在成为一个库,如果需要,必须将其与应用程序捆绑在一起,除非您在已为您捆绑了该捆绑件的环境中操作。
西奥多·默多克

69

XStream非常擅长将对象序列化为XML,而无需进行大量配置和花费!(已获得BSD许可)。

我们在一个项目中使用它来替换普通的旧Java序列化,并且它几乎可以立即使用。


3
它非常有用,但是在复杂树结构(例如带有非字符串节点对象的JGraph)上可能会出现问题。
mikek3332002 2010年

更简单,更好的解决方案
daitangio,2010年

我喜欢XStream。唯一的事情是我不明白为什么在实际的XML之前添加字符。
James P.

17

“简单XML序列化”项目

您可能需要查看简单XML序列化项目。这是我在.Net中找到的最接近System.Xml.Serialization的东西。


但是,它确实需要每个字段的映射注释。
mP。

1
不正确,我不需要。您可以更改默认行为,它将仅使用当前字段。
damluar 2011年

1
我也衷心支持“简单”。我已经在几个项目上成功使用了它。“简单”确实 JAXB简单得多。当您有相对简单的需求时最合适:将需要写入存储中的对象稍后再重新水化为对象。JAXB具有更多的功能和灵活性,但这是一种“ 80/20”的事情,在大多数项目中,大多数时候,您可能只需要简单的功能子集。
罗勒·布尔克

如果只需要1:1映射,效果很好。如果您的类不断发展并且仍然需要反序列化旧的XML,则会遇到问题,因为文档和错误消息都有些含糊。诊断问题通常是可行的,但弄清楚如何解决可能要花几天时间。
toolforger

13

JAXB是JDK标准版本1.6+的一部分。因此FREE,无需额外的库即可下载和管理。一个简单的例子可以在这里找到

XStream似乎已经死了。最近的更新是在2008年12月6日。 Simple看起来像JAXB一样容易和简单,但是我找不到任何许可信息来评估它以供企业使用。


4
XStream并不死,它只是成熟且稳定的-意味着没有太多要添加到核心功能上的东西。实际上,JAXB参考实现也是如此,在过去的几年中活动很少。
StaxMan 2011年

9

值得一提的是,从1.4版开始,Java具有类java.beans.XMLEncoder和java.beans.XMLDecoder。这些类执行XML编码,至少与XML序列化非常相似,并且在某些情况下可以为您解决问题。

如果您的类的getter和setter遵循JavaBeans规范,则此方法易于使用,并且不需要架构。有以下警告:

  • 与普通的Java序列化一样
    • 编码和解码在InputStream和OutputStream上运行
    • 该过程使用熟悉的writeObject和readObject方法
  • 与普通的Java序列化相反
    • 编码和解码也会导致构造函数和初始化程序被调用
    • 不管您的类是否实现了可序列化,编码和解码均有效
    • 不考虑瞬变修饰符
    • 仅适用于具有公共构造函数的公共类

例如,采用以下声明:

public class NPair {
  public NPair() { }
  int number1 = 0;
  int number2 = 0;
  public void setNumber1(int value) { number1 = value;}
  public int getNumber1() { return number1; }
  public void setNumber2(int value) { number2 = value; }
  public int getNumber2() {return number2;}
}

执行此代码:

NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();

将导致以下文件:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
 <object class="NPair">
  <void property="number1">
   <int>12</int>
  </void>
  <void property="number2">
   <int>13</int>
  </void>
 </object>
</java>

请注意,java.beans.XMLDecoder与用户提供的数据一起使用可能会在您的代码中引入任意代码执行漏洞。
aventurin

2

如果您有用于XML的架构,那么XMLBeans可以很好地工作。它为模式创建Java对象,并创建易于使用的解析方法。


0

如果您在谈论对象的XML自动序列化,请查看Castor

Castor是Java [tm]的开源数据绑定框架。这是Java对象,XML文档和关系表之间的最短路径。Castor提供Java到XML的绑定,Java到SQL的持久性等。


0

通常,如果需要创建可序列化为XML的对象,则通常使用jaxbXMLBeans。现在,我可以看到XStream可能是非常有用的,因为它是非侵入性的并且具有非常简单的api。我会尽快使用它,并可能会使用它。我注意到的唯一缺点是,我无法自行创建对象的ID进行交叉引用。

@Barak Schiller
感谢您发布指向XStream的链接!


问题是jaxb和xmlbeans需要映射模式和arent auto ...
mP。


0

如果您想要一个结构化的解决方案(例如ORM),那么JAXB2是一个很好的解决方案。

如果您想要像DOT NET这样的序列化,则可以使用 JavaBeans组件的长期持久性

选择取决于序列化的使用。


-1
public static String genXmlTag(String tagName, String innerXml, String properties )
{
    return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}

public static String genXmlTag(String tagName, String innerXml )
{
    return genXmlTag(tagName, innerXml, "");
}

public static <T> String serializeXML(List<T> list)
{
    String result = "";
    if (list.size() > 0)
    {
        T tmp = list.get(0);
        String clsName = tmp.getClass().getName();
        String[] splitCls = clsName.split("\\.");
        clsName = splitCls[splitCls.length - 1];
        Field[] fields = tmp.getClass().getFields();

        for (T t : list)
        {
            String row = "";
            try {
                for (Field f : fields)
                {
                    Object value = f.get(t);
                    row += genXmlTag(f.getName(), value == null ? "" : value.toString());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            row = genXmlTag(clsName, row);

            result += row;
        }
    }

    result = genXmlTag("root", result);
    return result;
}

许多问题:重塑Class#getSimpleName ***重塑PropertyDescriptor ***假定所有属性都是可访问的字段***不缓存反射结果(缓慢)***无法自定义任何内容(例如,我需要替换类和文件名)***无需反序列化
toolforger
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.