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を参照できます