Java JSONテクノロジーフレームワークの選択と例
JSON
JSONは英語でJavaScript Object Natationと呼ばれ、key:valueキー値ペアでデータを格納し、xmlフォーマットに比べてJSONは軽量レベルのデータ交換フォーマットである.Javascriptという単語に惑わされないでください.実際にJSONはデータ形式にすぎず、具体的な言語とは関係ありません.JSONはすでに業界に広く応用されている.例えば、現在のNoSQLデータベースのストレージの多くはkey:valueストレージ構造を採用している.Mongoを例にとると、そのスクリプト構文はJavascriptを直接使用することもある.データ転送時には、JSONフォーマットを採用することも広く応用され、ほとんどのオープンAPIはJSONモードのデータ出力を開放している.ajaxがデータを要求する場合、jsonフォーマットも広く推奨されている.jsonの詳細はjsonの公式サイトを見ることができますhttp://json.org.
Java transientキーワード
JAVA仕様原文The transient marker is not fully specified by the Java Language Specification but is used in object serialization to mark member variables that should not be serialized.javaは、保存とネットワーク転送を容易にするために、シリーズ化されたオブジェクトメカニズムを有し、transientは、現在シリーズ化されたくないメンバーオブジェクトを指定するために使用することができる.例を挙げてtransientのアプリケーションを説明します.Mongo+MorphiaオープンソースプロジェクトでJava POのメンバーにtransientを指定すると、そのメンバーデータはMongoデータベースに格納されません.もう1つの応用シーンはここで述べるJSONであり、JAVA POがReference(MongoのReference)またはLazyLoading(Hibernate LazyLoadingの概念と理解できる)を使用している場合、ほとんどのオープンソースJAVA JSON関連項目は、これらのReference、LazyLoadingオブジェクトを自動的にロードし、POが相互参照を形成するとデッドサイクルとなり、デッドサイクルが形成されていなくても,クライアントに大量の不要なデータが出力されるリソースの浪費は侮れない.transientを加えるのは解決策です.
JAVAに基づくJSONの主なオープンソースプロジェクトとその対比
Jsonオープンソースプロジェクトはorg.json、JSON-Lib、jsontool、Jackson、Gson、SimpleJSONなど非常に多く、その後、いくつかのjsonオープンソーステストデータの比較を専門に見た後、fastjsonを採用することにした.2つのテストデータのセットを示します.まず大侠wangym(元ブログhttp://wangym.iteye.com/blog/738933)によるJackson、JSON-Lib、Gsonのテスト結果を見てみましょう
JSON回転Bean、5スレッド同時、約200バイトオブジェクト、1千万回変換:
Jackson
JSON-lib
Gson
スループット
64113.7
8067.4
13952.8
合計時間(秒)
155
1238
700
Bean回転JSON、5スレッド同時、約200バイトオブジェクト、1千万回変換:
Jackson
JSON-lib
Gson
スループット
54802
15093.2
17308.2
合計時間(秒)
181
661
560
どの形式の変換でも,Jackson>Gson>Json−libであることが明らかになった.
ジャックソンの処理能力はJson-libより10倍ほど高い
その後、温度の少ないfastjsonとJSON-Lib、Simple-JSON、Jacksonの性能テストの比較データを取ります.
パフォーマンスの比較
テストケース
JSON-Lib
Simple-JSON
Fastjson
Jackson
IntArray1000Decode
3,626
1,431
563
596
StringArray1000Decode
2,698
2,283
677
774
Map100StringDecode
515
597
208
230
機能の比較
とくせい
JSON-Lib
Simple-JSON
Fastjson
Jackson
シーケンス化サポート配列
サポートされていません
サポートされていません
サポート
サポート
シーケンス化サポートEnum
サポートされていません
サポートされていません
サポート
サポート
JavaBeanのサポート
直接サポートしない
直接サポートしない
サポート
サポート
Fastjsonはパフォーマンスの面で、jacksonを含む現在のjava json proccesorをすべて超えていることがわかります.
FastJsonアプリケーションの例
1、Jquery ajax要求fastjsonデータを利用してユーザーリストの例を表示する実現
//User POオブジェクトの定義
public class User implements Serializable {
private static final long serialVersionUID = 1738399846398814044L;
private String userid;
private String username;
// Refrence Lazyloading
@Refrence
private UserDetail userDeatil;
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this. username = username;
}
public UserDetail getUserDetail() {
return userDetail;
}
public void setUserDetail (UserDetail userDetail) {
this. userDetail = userDetail;
}
}
//UserDetail POオブジェクトの定義
public class UserDetail implements Serializable {
private static final long serialVersionUID = 1738399846398814045L;
private String address;
public String getAddress() {
return address;
}
public void setAddress (String address) {
this. address = address;
}
}
Actionを作成し、List
….
List<User> ls= userService.getUserList();
PrintWriter out = null;
try {
out = getResponse().getWriter();
out.write(JSON.toJSONString(ls));
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
}
…
jquery ajaxリクエストの作成ユーザーリストの作成
$.ajax({
type:"GET",
url:"/user/getuserlist", // action
dataType:"json",
cache:false,
success: function(users){
var html=””;
if(users.length>0){
for(var i in users){
html=html+”username:”+users[i]+username+” address:”+users[i].userDetail.address;
}
alert(html);
}
});
2、ReferenceとLazyLoadingによる死循環問題をどのように解決しますか?
上記の例からfastjsonはuserDetailのaddressデータを正しく取り出し、実際にはすべてのjsonオープンソースプロジェクトがこの関連取り出しをサポートしていることがわかります.しかし、userDetailの下のデータを必要としない場合もあります.関係のないデータを自動的にロードしたり、デッドサイクルを生成したりしたら、どうすればいいのでしょうか.
1つ目の方法:
前述したように、User POのUserDetail定義を
private transient UserDetail userDeatil;
2つ目の方法:
1つ目の方法は共通の方法で、他のjsonオープンソースプロジェクトを使用しても効果が得られ、FastJsonで@JSOnField(serialize=false)を使用することもできます.
@JSONField(serialize=false)
private transient UserDetail userDeatil;
もちろんJSOnFieldには、メンバーのカスタムシーケンス化を実現するために他のパラメータを指定することもできます.一般的に、メンバーが非シーケンス化できると判断した場合は、まずtransientを使用することをお勧めします.ただし、transientを指定すると、Userオブジェクトの下に長いフィールドremarkがあり、remarkにtransientが指定されている場合、Mongoデータベースを使用する場合など、ページにコミットされたremarkデータがデータベースに保存されず、transientキーワードを付けていないフィールドが正常に保存されるという問題が発生することがあります.この場合@JSOnFieldを使用して問題を解決できます.
3つ目の方法:
シーンAの場合はremarkをシリーズ化する必要があり、シーンBの場合はシリーズ化する必要がないなどのさらなる最適化があれば、fastjsonカスタムフィルタを使用し、fastjsonはname、property、valueの3種類のフィルタリングを行い、propertyの例でList
….
List<User> ls= userService.getUserList();
PropertyFilter filter = new PropertyFilter() {
public boolean apply(Object source, String name, Object value) {
if("remark ".equals(name)) {
return true;
}
return false;
}
};
SerializeWriter sw = new SerializeWriter();
JSONSerializer serializer = new JSONSerializer(sw);
serializer.getPropertyFilters().add(filter);
serializer.write(ls);
PrintWriter out = null;
try {
out = getResponse().getWriter();
out.write(sw.toString());
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
}
…
このようにシーンBに遭遇したときに第3の方法でremarkというメンバーをフィルタリングし、シーンAの場合はフィルタを付けなくてもよい.
詳細fastjson情報はhttp://code.alibabatech.com/wiki/display/FastJSON/Homeを参照できます