5

假设我想在 XML 中存储很多小的配置对象,并且我不太关心格式。JDK 中内置的XMLDecoder类可以工作,据我所知,XStream以类似的方式工作。

每个图书馆的优势是什么?

4

8 回答 8

9

我真的很喜欢XStream 库。由于提供的 Java 对象,它在输出相当简单的 xml 方面做得非常好。它也适用于从 xml 复制对象。而且,无论如何,我们的第 3 方库之一已经依赖它。

  • 我们选择使用它是因为我们希望我们的 xml 是人类可读的。使用别名功能使它变得更好。

  • 如果您希望对象的某些部分以更好的方式反序列化,您可以扩展库。我们在一个案例中这样做了,因此文件将具有一组度、分和秒来表示纬度和经度,而不是两个双精度值。

两分钟的教程总结了基本用法,但是为了将信息集中在一个地方,我会尝试在这里总结一下,稍微短一点。

// define your classes
public class Person {
  private String firstname;
  private PhoneNumber phone;
  // ... constructors and methods
}

public class PhoneNumber {
  private int code;
  private String number;
  // ... constructors and methods
}

然后使用库写出xml。

// initial the libray
XStream xstream = new XStream();
xstream.alias("person", Person.class); // elementName, Class
xstream.alias("phone", PhoneNumber.class); 

// make your objects
Person joe = new Person("Joe");
joe.setPhone(new PhoneNumber(123, "1234-456"));

// convert xml
String xml = xstream.toXML(joe);

您的输出将如下所示:

<person>
  <firstname>Joe</firstname>
  <phone>
    <code>123</code>
    <number>1234-456</number>
  </phone>
</person>

回去:

Person newJoe = (Person)xstream.fromXML(xml);

XMLEncoder 是为 Java bean 序列化提供的。我上次使用它时,该文件看起来相当讨厌。如果真的不在乎文件的外观,它可以为您工作,并且您可以避免第 3 方依赖,这也很好。我希望使序列化更漂亮的可能性对于 XMLEncoder 也将是一个更大的挑战。

如果您不给名称起别名,XStream 会输出完整的类名。如果上面的 Person 类有

package example;
xml 将具有“example.Person”,而不仅仅是“person”。

于 2008-09-18T21:28:29.907 回答
4

另一个建议:考虑使用 JAXB ( http://jaxb.dev.java.net )。如果您使用的是 JDK 1.6,它是捆绑的,请查看“javax.xml.bind”了解详细信息,因此无需额外的外部 jar。

JAXB 相当快。我也喜欢 XStream,但它有点慢。此外,XMLEncoder 有点像玩具(与其他选项相比)......但如果它有效,那么使用它并没有什么坏处。

另外:JAXB 的一个好处是您还可以使用它绑定部分文档(子树);无需为整个文件创建对象。为此,您需要使用 Stax (XMLStreamReader) 指向子树的根元素,然后绑定。无需使用 SAX,即使对于大多数大文件,只要可以逐块处理即可。

于 2009-02-10T20:48:51.023 回答
1

如果您计划将所有这些配置对象存储在一个文件中,并且该文件将非常大,那么您上面概述的两个选项都可能会占用大量内存,因为它们都需要将整个文件读入内存以被反序列化。

如果内存使用是一个问题(包含 XML 的文件会非常大),我推荐SAX

如果内存使用不是问题(包含 XML 的文件不会很大),我会使用默认 JRE(在本例中为 XMLDecoder)中包含的任何内容来删除第 3 方依赖项。

于 2008-09-18T19:41:40.320 回答
1

我也更喜欢XStream,因为它非常易于使用和扩展。如果您使用默认设置,您可以快速开始。如果您需要自定义行为,它有一个非常干净的 API 和许多扩展点,因此您可以非常精细地控制要调整的内容,而不会干扰编组过程的其他部分。

由于 XStream 创建的 XML 看起来不错,因此手动编辑也很简单。如果输出不能满足您的需求,并且可用转换器的长列表不包含您需要的转换器,那么编写自己的转换器相当简单。

一个很大的优点也是他们主页上的好文档。

于 2008-09-19T07:57:33.780 回答
1

我总是觉得 XStream 很诱人,因为它很容易上手。但是,我总是最终更换它。它真的很麻烦,它的收集处理可能需要做很多工作。

因此,我通常会切换到 JAXB。它比 XStream 健壮得多,几乎没有错误,而且更灵活。

于 2009-09-23T18:27:51.847 回答
1

除了@jay 回答示例:

代码:

PortfolioAlternateIdentifier identifier = new PortfolioAlternateIdentifier();
identifier.setEffectiveDate(new Date());
identifier.setSchemeCode("AAA");
identifier.setIdentifier("123456");

使用 XStream 的输出:

<PortfolioAlternateIdentifier>
 <effectiveDate>2014-05-02 20:14:15.961 IST</effectiveDate>
 <schemeCode>AAA</schemeCode>
 <identifier>123456</identifier>
</PortfolioAlternateIdentifier>   

使用 XMLEncoder 的输出:

<?xml version="1.0" encoding="UTF-8"?> 
 <java version="1.6.0_38" class="java.beans.XMLDecoder"> 
   <object class="PortfolioAlternateIdentifier"> 
    <void property="effectiveDate"> 
  <object class="java.util.Date"> 
   <long>1399041855961</long> 
  </object> 
    </void> 
 <void property="identifier"> 
  <string>123456</string> 
 </void> 
   <void property="schemeCode"> 
    <string>AAA</string> 
   </void> 
  </object> 
</java> 
于 2014-05-02T14:54:44.753 回答
0

Java 还有一个新的实用程序类,旨在存储配置中典型的键值对集。它是老式的,但非常简单和方便。这是通过java.util.Properties类完成的,这是一个带有序列化选项的 Map 对象。除非您存储整个对象,否则这可能就是您所需要的。

于 2009-09-23T18:23:59.000 回答
-1

如果您要持久化大量对象或者您的系统需要多线程,您应该避免像瘟疫那样使用 XMLEncoder/XMLDecoder。有关可怕的详细信息,请参见http://matthew.mceachen.us/blog/do-not-want-xmlencoder-129.html

如果您必须使用 XML,XStream 非常棒。但是问问自己是否真的需要使用 XML。这是一个序列化基准项目,可能会让您获得更好的解决方案:

http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

于 2010-03-25T17:18:23.877 回答