多数の小さな構成オブジェクトを XML で格納したいとしますが、形式はあまり気にしません。JDK に組み込まれている XMLDecoder クラスは機能します。私が聞いたところでは、XStreamも同様に機能します。
各ライブラリの利点は何ですか?
私はXStream ライブラリがとても気に入っています。提供された Java オブジェクトの結果として、かなり単純な xml を出力するという非常に優れた仕事をします。xml からオブジェクトを再現するのにも最適です。そして、サードパーティのライブラリの 1 つがすでにそれに依存していました。
これを使用することにしたのは、xml を人間が読めるようにしたかったからです。エイリアス機能を使用すると、より便利になります。
オブジェクトの一部をより適切な方法で逆シリアル化する場合は、ライブラリを拡張できます。1 つのケースでこれを行ったので、ファイルには 2 つの double ではなく、緯度と経度の一連の度、分、および秒が含まれます。
2 分間のチュートリアルで基本的な使い方を要約していますが、情報を 1 か所にまとめるために、ここでは少し短くまとめてみます。
// 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 シリアライゼーション用に提供されています。前回使用したとき、ファイルはかなり厄介に見えました。ファイルがどのように見えるかを本当に気にしない場合は、それでうまくいく可能性があり、サードパーティの依存関係を回避できます。これも素晴らしいことです。シリアライゼーションをよりきれいにする可能性は、XMLEncoder でもより困難になると思います。
名前に別名を付けない場合、XStream は完全なクラス名を出力します。上記の Person クラスが
package example;
xml には、「person」ではなく「example.Person」が含まれます。
XStreamは非常に使いやすく、拡張しやすいので、私もXStreamを好みます。デフォルトの設定を使用している場合は、すぐに開始できます。動作をカスタマイズする必要がある場合は、非常にクリーンなAPIと多くの拡張ポイントがあるため、マーシャリングプロセスの他の部分に干渉することなく、微調整したいものを非常にきめ細かく制御できます。
XStreamによって作成されたXMLは見栄えがよいため、手動編集も簡単です。出力がニーズを満たさず、使用可能なコンバーターの長いリストに必要なものが含まれていない場合は、独自のコンバーターを作成するのはかなり簡単です。
大きなプラスは、彼らのホームページの良いドキュメントでもあります。
XStreamはとても簡単に始められるので、いつもとても魅力的です。しかし、必ず交換してしまいます。それは本当にかなりバグがあり、そのコレクションの処理には多くの作業が必要になる可能性があります。
その結果、私は通常JAXBに切り替えます。XStreamよりもはるかに堅牢で、バグがほとんどなく、柔軟性があります。
例を含む@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>
これらすべての構成オブジェクトを 1 つのファイルに格納することを計画していて、そのファイルが非常に大きくなる場合、上で概説した両方のオプションは、ファイル全体をメモリに読み込む必要があるため、メモリを大量に消費する可能性があります。デシリアライズされます。
メモリ使用量が懸念される場合 (XML を含むファイルは非常に大きくなります)、SAXをお勧めします。
メモリ使用量が問題にならない場合 (XML を含むファイルがそれほど大きくない場合)、サード パーティの依存関係を削除するためだけに、デフォルトの JRE (この場合は XMLDecoder) に含まれるものを使用します。
Java には、構成に典型的な Key-Value ペア セットを格納することを目的とした新しいユーティリティ クラスもあります。古いスタイルですが、とてもシンプルで便利です。これは、シリアル化オプションを持つ Map オブジェクトであるjava.util.Propertiesクラスを介して行われます。オブジェクト全体を保存する場合を除き、これで十分かもしれません。
自明ではない数のオブジェクトを永続化する場合、またはシステムをマルチスレッド化する必要がある場合は、疫病のように 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