2013年03月27日
JavaオブジェクトをXMLへシリアライズ, デシリアライズする時に知っておきたいライブラリ2選 - Simple & XStream
データベースを使う程では無いがオブジェクの状態を保存しておきたい、そんな時にはJavaオブジェクトのシリアライズ(直列化)、デシリアライズ(非直列化)が頭に浮かびます。この方法には幾つかありますが、シリアライズされたデータを人が理解・編集出来る、外部システム/他言語間でのデータ交換にも利用することを望むのであればXMLフォーマットは大変便利です。
僕はアプリケーションの設定ファイル <-> Java オブジェクト変換に使うことが多いですね。
今日は Simple/XStream という2つのJavaライブラリの使い方・特徴を紹介します。
Simpleを使ったJavaオブジェクトのXMLシリアライズとデシリアライズ
Simpleはその名の通りシンプル、高速を謳うシリアライズ・フレームワークで、実は僕もXMLへのシリアライズといえば最近までSimpleライブラリというイメージを持っていました。
まずは、プロジェクト・ページから最新のライブラリをダウンロードしましょう。
Simple 2.7
ダウンロードしたsimple-xml-x.x.x.jarをクラスパスに含めれば準備はおしまい。
stock.xmlを開いてみると・・・無事XMLへのシリアライズが行われました。
デシリアライズも基本は同じ。read()メソッドを使ってオブジェクト化します。
実行すると次のような出力になるはずです。
詳しい使い方は Tutorial ページをどうぞ。
XStreamもSimpleと同じくJavaオブジェクトのシリアライズ、デシリアライズを行いますが、より”シンプル”です。
XStream - About XStream
尚、アノテーションを使わない分、useAttrbuteFor()メソッドで属性になる変数名を指定してあげる手間は必要です。
こちらもItemクラスへのアノテーション(@XStreamAlias("アイテム"))追加で実装することも可能。
最後にデシリアライズ。これは次のようなコードになります。
うーん、XStreamは始めて触ったんですが、こちらの方が柔軟性があって迷う人にはオススメだなあ。
XStreamのチュートリアルはこちらからどうぞ。
Simple、XStreamどちらも高速を謳っていますが、同じ条件ならばどちらが早いのでしょうか?
Simple 2.7
ダウンロードしたsimple-xml-x.x.x.jarをクラスパスに含めれば準備はおしまい。
ここでは2つのクラスを使ってシリアライズ、デシリアライズしてみます。
まずはシンプルなItemクラス。
後もうひとつ、ItemオブジェクトをListに保存するStockクラスを用意します。
Simpleを使う場合、この2つのクラスにアノテーションを追加します。
@Element は要素、required = false は必須値では無いことを指し示します。同じようにStockクラスも次のように変更します。
Stockクラスではlabelを属性とする為に @Attribute アノテーションを新たに使っています。
public class Item {
private String name = null;
private double price = 0.0;
private String descr = "";
public Item(String name, double price) {
this.name = name;
this.price = price;
}
public Item() {
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String getDescr() {
return descr;
}
public void setDescr(String descr) {
this.descr = descr;
}
}
後もうひとつ、ItemオブジェクトをListに保存するStockクラスを用意します。
import java.util.ArrayList;
import java.util.List;
public class Stock {
private String label = "Item stock";
private List<Item> items = new ArrayList<Item>();
public void addItem(Item i) {
items.add(i);
}
public Item getItem(int i) {
return items.get(i);
}
public int getNumStocks() {
return items.size();
}
public boolean removeItem(Item i) {
return items.remove(i);
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
Simpleを使う場合、この2つのクラスにアノテーションを追加します。
import org.simpleframework.xml.Element;
public class Item {
@Element
private String name = null;
@Element
private double price = 0.0;
@Element(required = false)
private String descr = "";
public Item(String name, double price) {
this.name = name;
this.price = price;
}
public Item() {
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public String getDescr() {
return descr;
}
public void setDescr(String descr) {
this.descr = descr;
}
}
@Element は要素、required = false は必須値では無いことを指し示します。同じようにStockクラスも次のように変更します。
import org.simpleframework.xml.Element; public class Item { @Element private String name = null; @Element private double price = 0.0; @Element(required = false) private String descr = ""; public Item(String name, double price) { this.name = name; this.price = price; } public Item() { } public String getName() { return name; } public double getPrice() { return price; } public String getDescr() { return descr; } public void setDescr(String descr) { this.descr = descr; } }
Stockクラスではlabelを属性とする為に @Attribute アノテーションを新たに使っています。
ここまで出来たらまずはシリアライズ(直列化)してみます。次のコードはStock/Itemインスタンスを生成し、Persisterを使ってstock.xmlにシリアライズしています。
Stock stock = new Stock();
stock.addItem(new Item("りんご", 100.0));
stock.addItem(new Item("みかん", 50.0));
stock.addItem(new Item("ぶどう", 150.0));
Serializer serializer = new Persister();
File xml = new File("stock.xml");
serializer.write(stock, new BufferedWriter(new FileWriter(xml)));
stock.xmlを開いてみると・・・無事XMLへのシリアライズが行われました。
<stock label="Item stock">
<items class="java.util.ArrayList">
<item>
<name>りんご</name>
<price>100.0</price>
<descr></descr>
</item>
<item>
<name>みかん</name>
<price>50.0</price>
<descr></descr>
</item>
<item>
<name>ぶどう</name>
<price>150.0</price>
<descr></descr>
</item>
</items>
</stock>
デシリアライズも基本は同じ。read()メソッドを使ってオブジェクト化します。
Serializer serializer = new Persister();
File xml = new File("stock.xml");
Stock stock = serializer.read(Stock.class, xml);
for (int i=0; i< stock.getNumStocks(); i++) {
System.out.println(stock.getItem(i).getName());
}
実行すると次のような出力になるはずです。
りんご
みかん
ぶどう
詳しい使い方は Tutorial ページをどうぞ。
XStreamを使ったJavaオブジェクトのXMLシリアライズとデシリアライズ
XStreamもSimpleと同じくJavaオブジェクトのシリアライズ、デシリアライズを行いますが、より”シンプル”です。
まずはプロジェクト・ページから Binary distribution をダウンロードしましょう。
XStream - About XStream
zipファイルに含まれるjarファイルのうち、最低限必要になるのはxstream-x.x.x.jarとxstream/xpp3_min-x.x.x.jar, xstream/xmlpull-x.x.x.x.jarの3つ。
これをクラスパスに含めれば準備はおしまい。
早速、Simpleと同じくStock、Itemオブジェクトをシリアライズしてみましょう。
こちらがそのコード。
Stock stock = new Stock();
stock.addItem(new Item("りんご", 100.0));
stock.addItem(new Item("みかん", 50.0));
stock.addItem(new Item("ぶどう", 150.0));
XStream xs = new XStream();
xs.useAttributeFor(Stock.class, "label");
File xml = new File("stock.xml");
xs.toXML(stock, new BufferedWriter(new FileWriter(xml)));
え、アノテーションは必要ないのか?、そうなんです。XStreamではアノテーションは必須ではないんです(使えますが)。
このメリットは対象となるクラスにシリアライズに関わるコードが含まれなくなることです。IBM developerWorks JapanのSimple紹介ページではSimple利用すれば対象オブジェクトは POJO (Plain Old Java Object) のままで良いと紹介していますが、これを見る限りXStreamの方がよりPOJOですね。
尚、アノテーションを使わない分、useAttrbuteFor()メソッドで属性になる変数名を指定してあげる手間は必要です。
生成されたstock.xmlの中身がこちら。
<Stock label="Item stock">
<items>
<Item>
<name>りんご</name>
<price>100.0</price>
<descr></descr>
</Item>
<Item>
<name>みかん</name>
<price>50.0</price>
<descr></descr>
</Item>
<Item>
<name>ぶどう</name>
<price>150.0</price>
<descr></descr>
</Item>
</items>
</Stock>
Simpleとは少し違ってJavaのコードに関する情報は含まれません(Simpleを使った場合にも、Stockクラスの書き方次第ではJava具象クラスの情報を消すことができます)。
この他にもXStreamでは要素の alias 名も簡単に利用出来るという特徴があります。先ほどのコードに次の一行を追加すれば、<Item> 要素は <アイテム>に置換してXML出力されます。
- snip -
xs.alias("アイテム", Item.class);
こちらもItemクラスへのアノテーション(@XStreamAlias("アイテム"))追加で実装することも可能。
最後にデシリアライズ。これは次のようなコードになります。
XStream xs = new XStream();
xs.useAttributeFor(Stock.class, "label");
Stock stock = (Stock) xs.fromXML(xml);
うーん、XStreamは始めて触ったんですが、こちらの方が柔軟性があって迷う人にはオススメだなあ。
XStreamのチュートリアルはこちらからどうぞ。
Simple/XStreamのシリアライズ・デシリアライズ性能比較
Simple、XStreamどちらも高速を謳っていますが、同じ条件ならばどちらが早いのでしょうか?
Itemオブジェクトを100000(10万)件ストックしたStockオブジェクトのシリアライズ、デシリアライズ所要時間を計測した結果がこちら。
Simple | XStream | |
シリアライズ(ミリ秒) | 3237 | 1778 |
デシリアライズ(ミリ秒 | 1582 | 2412 |
比較的にXStreamはシリアライズが早く、Simpleはデシリアライズが早いという結果になりました。
双方の時間を合わせればXStreamに軍配が上がるので性能面ではXStreamの勝ち・・・かな?
最新Javaコーディング作法 プロが知るべき、107の規約と21の心得
posted with amazlet at 13.03.26
森崎 雅稔
日経BP社
売り上げランキング: 137,854
日経BP社
売り上げランキング: 137,854
XML Hacks ―エキスパートのためのデータ処理テクニック
posted with amazlet at 13.03.26
Michael Fitzgerald 佐藤 直生 木下 哲也 福竜興業
オライリージャパン
売り上げランキング: 270,580
オライリージャパン
売り上げランキング: 270,580