JSONとXML、および少しのリファクタリング

はじめに



RIAを作成する分野で作業する場合、遅かれ早かれ、サーバーとそのクライアント間でデータを転送するためのプロトコルの選択について考える必要があります。 以前にXMLを無条件で使用していた場合、JSONを優先してこの問題の優先順位を変更することを考えるようになりました。 クライアントについて話すとき、私は上記と間違えなかったので、ますます多くの顧客が彼らのサービスのためにモバイル版を必要とします、そして、それゆえ、私はいくつかのクライアント(ブラウザと、例えばiPhoneアプリケーション)とそれらのバージョンをサポートできるサーバーインフラストラクチャを作成することを考えなければなりません。 XMLはすべてのパラメーターに適しているようですが、疑問があります。



疑い



過去数年にわたって、私はXMLの広範な使用を注意深く観察してきました。はい、形式は普遍的ですが、その尺度を知る必要があります。 XMLの主なフラグは、データを保存するための機械可読形式および人間可読形式です;読みやすいことに注意してください。 文献では、XMLはデータを格納するために設計された階層構造であり、視覚的に構造をツリーとして表すことができるという言及を見つけるでしょう。



そして、ここで最初の疑問が生じます。しかし、小さなツリー、200個のノードを取り、XMLとして保存すると、それはただ読み取られます。 ハイライト付きの特別なエディタを持たない人がそのようなファイルを読むことはほとんど不可能です(特に、ハイフンとタブなしで同じ行に書かれている場合)。 この声明に反対することは困難です。



したがって、フォーマットの人間の可読性を利点として破棄し、XMLを主にサービス、プログラム、またはプラットフォーム間の通信の手段、システム間の通信のプラットフォームに依存しない手段として考慮する必要があります。



上記の正当な立場に基づいて、2番目の疑問が生じます。 高価じゃない? この場合、プロセッサ時間が推定されます。 最後のプロジェクトでは、パフォーマンスを測定する必要があり(「プロファイル」と言うことができます)、ボトルネックの1つはXMLでのオブジェクトのシリアル化と、そのオブジェクトからの転生でした。 手を頻繁に洗う必要があると考えられますが、生産性は向上しましたが、開発チームを喜ばせるほどではありませんが、ランクの清潔さのためにほぼ1か月間苦労しました。



疑念の最後の、最軽量であると同時に根本的に修復不可能なのは、送信されるデータの量、つまり生成されたトラフィックの量に関連しています。 顧客はほとんどいませんでしたが、この問題は存在しませんでした。 ただし、モバイルクライアントがサービスに登場し、同時に大勢の企業の人々がシステムに突入したとき、生成されたトラフィックの量は、クライアントアプリケーション(大規模な)を操作するためのプロトコルとして、XML(ホワイトノイズ生成)の冗長性を明確に示していました。



XMLを使用することの複雑さは、このテクノロジーが解決する問題の複雑さを上回ると結論付けることができます。 XMLの作成者である[TB、TB2]もそうであるように、あなた自身が多くの議論と反対を思いつくことができます。 しかし、XMLを優先して、サーバーを同期するためのプロトコルとしてXMLを使用することはほぼ完璧であり、開発自動化ツールを使用するとリラックスして楽しむことができます。 しかし、クライアントトラフィックの問題により、JSONデータの表示形式に注意を払わざるを得ませんでした。



代替案



JSONに関する主な情報源は公式サイト[JSON]であり、次の定義が含まれています。JSON(JavaScript Object Notation)は、人とコンピューターの両方による読み取りと書き込みに便利な単純なデータ交換形式です。 JSONを大衆に宣伝することに焦点を当てた定義を即座に却下し、フォーマットはテキスト、オープン、シンプル、そして十分に文書化されている[JSONdoc]であることに注意してください。



私の意見では、JSON形式の人間の可読性はXMLよりもさらに低いです。 このステートメントを検証するには、twitter.com検索APIに要求を行います(例: search.twitter.com/search.json?q=golodnyj )。API自体を読み取らずに結果を解釈してみてください。 少なくともJSONはセマンティクスを伝えないが、コンテンツを表現することを目的としているため、難易度が高くなります。 上記に基づいて、JSONは、オブジェクトの転送に焦点を合わせた、クライアント/サーバーアプリケーションのペアリングのための、テキストベースのオープンで軽量なプロトコルとして定義する必要があります。



JSONの使用への移行により、ユーザートラフィックの量が大幅に(最大25〜30%)削減され、サービスのネットワークインフラストラクチャの負荷が大幅に削減されました。 ただし、ご理解のとおり、生成と解析をXMLからJSONに置き換える必要がありました。 これには良いことは何もないように思えます-重要なコードのリファクタリング、デバッグ、および長時間のテストですが、幸運でした。



今日のヒーロー



個々の分野における人類の救世主はXStream [XS]フレームワークでした。幸いなことに、これは実験が行われたシステムのその部分でXMLを正確に操作するために使用されました。



例として、コンストラクター、ゲッター、セッターという3つの属性を持つClientクラス(付録1の完全なソースコードを参照)を考えます。



package ru.golodnyj.lection.json;



public class Client {

private String userName;

private boolean verified;

private int userId;



public Client( String userName, boolean verified, int userId) {

this .userName = userName;

this .verified = verified;

this .userId = userId;

}

...

}




* This source code was highlighted with Source Code Highlighter .






また、ConsoleJSONクラス(付録2)では、最初にClientクラスのインスタンスのXML形式へのシリアル化、次にJSONへのシリアル化を示します。



package ru.golodnyj.lection.json;

...



public class ConsoleJSON {

public static void main( String [] args) {

Client c = new Client( "name" , true , 5);



// XML

XStream xstream = new XStream( new DomDriver());

String xml = xstream.toXML(c );

System. out .println( "xml " + xml.length() + " : \n" + xml);



// JSON

XStream xstream1 = new XStream( new JsonHierarchicalStreamDriver());

String json = xstream1.toXML(c );

System. out .println( "json " + json.length() + " : \n" + json);

}

}




* This source code was highlighted with Source Code Highlighter .






プログラムを開始すると、次の形式のコンソールにメッセージが表示されます。



xml 145 :

< ru.golodnyj.lection.json.Client >

< userName > name </ userName >

< verified > true </ verified >

< userId > 5 </ userId >

</ ru.golodnyj.lection.json.Client >

json 96 :

{"ru.golodnyj.lection.json.Client": {

"userName": "name",

"verified": true,

"userId": 5

}}




* This source code was highlighted with Source Code Highlighter .






最初にXMLマッピングがあります-結果の文字列は145文字の長さで、次にJSONは96文字の長さです。 このような単純なオブジェクトをシリアル化するときの行の長さの違いは非常に大きく、複雑な構造について言えます。 もちろん、XMLおよびJSONの出力はコンパクトにすることができます。たとえば、データ転送の場合、完全な標準クラス名とフォーマットされた出力はまったく重要ではありません。



出力を改善するために、XStreamのエイリアスメカニズムを使用して、文字列変数をクラス名にマッピングできます。 また、JSON形式の場合、ドライバーをフォーマット済みの出力を提供するJsonHierarchicalStreamDriver()からストリーム出力用のJettisonMappedXmlDriver()に変更する必要があります。



XStream xstream1 = new XStream( new JettisonMappedXmlDriver());

xstream1.alias(«client», Client. class );




* This source code was highlighted with Source Code Highlighter .






この場合、クライアントオブジェクトのインスタンスのJSONオプションの長さは57文字で、次のようになります。



{"client":{"userName":"name","verified":true,"userId":5}}





XMLからPOJOへの逆シリアル化のプロセスも簡単で、XStreamクラスのインスタンスのfromXML()メソッドを呼び出すことで構成されます。このメソッドには、JSON文字列がパラメーターとして渡され、データ型が続きます。



結論



ConsoleJSONクラスに再度注意を払うと、XMLからJSONへの出力を置き換えるのに必要なものがほとんどないことに気付くでしょう。 その結果、生成されるトラフィックの量を大幅に節約できます。 この特定の場合、サーバー側では、データ転送プロトコルをXMLからJSONに置き換えることを目的としたリファクタリングプロセスは非常に簡単であり、大きな労力を必要としませんでした。



文学



[TB] Tim Bray www.tbray.org/ongoing/When/200x/2003/03/16/XML-Prog

[TB2] Tim Bray www.tbray.org/ongoing/When/200x/2003/03/24/XMLisOK

[JSON] www.json.org

[JSONdoc] www.json.org/json-ru.html

[XS] xstream.codehaus.org



用途



付録1 dumpz.org/12012

付録2 dumpz.org/12013



All Articles