Web APIの次世代標準プロトコル「Atom Publishing Protocol」

第4回 Atom Publishing Protocolを試す

この記事を読むのに必要な時間:およそ 7 分

⑧.HTTPレスポンスボディを得る(ある場合に限る)(リスト8)

GET,POST,PUTでリクエストを出し,HTTPレスポンスコードが200または201ならば,HTTPレスポンスにHTTPレスポンスボディが含まれています。このレスポンスボディどうするかはサーバ側の今後の処理次第です。リスト7ではレスポンスボディに含まれるサービス文書等のXML文書を,2パターンで取り出しています。1つ目のパターンはレスポンスボディをInputStreamで取り出しDOM化しています。DOM化することで今後,プログラム内で扱いやすいデータとなります。2つ目のパターンはString化するもので単純な出力用に使う程度でしょうか。

//リスト8
// DOM化
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilde	 db = dbf.newDocumentBuilder();
Document doc = db.parse(con.getInputStream());
/* String化
BufferedReader  reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
System.out.println("ResponseBody");
while((line = inputreader.readLine())!= null){
    System.out.println(line);
}
*/
⑨.XMLのDOM化,DOMの処理

次は,得られたDOMを操作して,必要な情報を取り出します。ここではJava SwingのJtreeを使って視覚的に表現したいと思います(Stringで出せれば十分だという方は話が細かくなりますので,読み飛ばしましょう。⁠⁠。

図1 java swingによるクライアント実装

図1 java swingによるクライアント実装

JTreeはDefaultMutableTreeNodeを引数とするコンストラクタを持っているので,DefaultMutableTreeNodeでツリーを構築して,そのルートをJTreeのコンストラクタに渡せば簡単にツリー構造を視覚化できます。実際には,まずDOMのルートノードをDefaultMutableTreeNodeでインスタンス化し,addchild()でその子ノードを順次ツリーに追加します。子ノードにエレメントノードがあると,それを新たなルートとしてadd.child()を再帰的に繰り返します。このようにすることでJTreeへ変換することが可能です。具体的にはリスト9のようになります。

//リスト9
//rootノードの作成
Node rootTag = doc.getDocumentElement();
DefaultMutableTreeNode root = new DefaultMutableTreeNode(rootTag.getNodeName());
//rootから前順序で再帰的にdocを辿る
addChildren(rootTag, root);
//Tree作成
JTree tree = new JTree(root);
//中略
private void addChildren(Node node, DefaultMutableTreeNode branch) {
  //branchに対して子ノードをaddする
  NodeList list = node.getChildNodes();
  //子ノードのうちアトリビュートノードだけを処理する
  NamedNodeMap attributes = node.getAttributes();
  for(int i=0; i<attributes.getLength(); i++){
    DefaultMutableTreeNode att = new DefaultMutableTreeNode( attributes.item(i));
    branch.add(att);		
  }
 //子ノードのうちエレメントノードとテキストノードを処理する		
 for( int i=0; i<list.getLength(); i++ ) {
    Node child = list.item( i );
    if(/*テキストノードならば*/){
       //テキストノードの処理  
       continue;
    }
    //エレメントノードの処理
    DefaultMutableTreeNode tn = new DefaultMutableTreeNode( child.getNodeName());
    branch.add( tn );
    //追加したエレメントノードをルートとして再帰的にツリーを構成
    addChildren(child,tn);
  }	
}

これでDOMからJteeに変換することができました。これに加えてイベント処理系を利用することで,簡易なGUIが作成できると思います。一方,GUI上におけるJTreeの内容をXML化したいとき(例えば,Tree上で編集して,その内容をPUTするような状況)はJtreeに加えられた更新をイベント処理でDOMと同期させます。そしてDOMからXMLへの変換を行います。これはTransrormer.fransformを使えば簡単に実現できます。リスト10ではDOMの内容をUTF-8でStringとして取り出しています。

//リスト10
try{
ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tr = tff.newTransformer();
tr.transform(new DOMSource(document), new StreamResult(bufferStream));
String st=bufferStream.toString("UTF-8");
}catch(Exception e){}

AtomPubクライアントの紹介

最後に,既存のAtomPubクライアントを幾つか紹介したいと思います。

APP Test Client
本稿で使わせてもらったJoeGregorioさんのAPP Test Siteのクライアントバージョンです。
the Ape
IETFのAtomPubワーキングループで議長を務めているTimBrayさんのクライアントです。ブラウザから使えます。
Atomic
AtomicはAtomPubを利用するためのFireFox用プラグインです。REST型のアプリケーションを開発するためのJava軽量フレームワーク"Restlet"を利用したAtomPubクライアント&サーバープロジェクト"atomojo"の一環で作成されました。このプラグインはまだ未実装な機能も多いですが,作者のAlex Milowskiさんが勢威製作中のようなので今後に期待です。
MobileAtomJ2ME
MobileAtomはJ2MEによる携帯アプリのAtomPubクライアントの実装です。2004年ごろのAtomPubの仕様をもとに作成されたものなので,HTTPメソッドのPUTとDELETEに対応するために,RFCでは認められていないSOAPを一部利用しています。しかし,ソースそのものは実装するときに参考になります。
Atomic
ウィザシステムの丸本さんのクライアントソフトです。和製ソフトでは一番有名かもしれません。

まとめ

最終回はAtomPubを試すと銘うって,ツール,実装方法,その他クライアントソフトを紹介しました。AtomPubは結局のところHTTP通信であるために,どのような試し方をしても理解や応用が容易であることがおわかりいただけたと思います。仮にRFC片手に自分で実装するとしても標準ライブラリの組み合わせだけでほぼ完結していまいます(RFCを理解する労力は翻訳によって軽減されるでしょう⁠⁠。このようにAtomPubは実装面においても非常に簡便であると言えます。これはAtomPubの設計思想が簡単・一般的であるRESTからブレなかったことに起因します。

また,AtomPubはRFC化されて間もないプロトコルです。今後は,ご紹介したツールをはじめRFC準拠の様々なクライアントが登場してくると予想されます。それらをウオッチすることでAtomPubがどのようなアレンジを加えられて市場に出現するか,どのように広まるか等を観察するのも面白いかもしれません。

最後に,この連載をきっかけにAtomPubの理解を深めていただけたり,少しでも何か使ってみよう・作ってみようと思っていただけたなら幸いです。

著者プロフィール

坂野大作(さかのだいさく)

NTTコミュニケーションズに入社後,先端IPアーキテクチャセンタにてモバイル,Webテクノロジ領域でアプリ開発・技術開発に取り組む。