Fastjson詳細介紹

jopen 10年前發布 | 22K 次閱讀 JSON開發包 fastjson

簡介

Fastjson是一個Java語言編寫的高性能功能完善的JSON庫。

高性能

fastjson采用獨創的算法,將parse的速度提升到極致,超過所有json庫,包括曾經號稱最快的jackson。并且還超越了google的二進制協議protocol buf。

支持標準

  • Fastjson完全支持http://json.org的標準,也是官方網站收錄的參考實現之一。
  • </ul>

    功能強大

    • 支持各種JDK類型。包括基本類型、JavaBean、Collection、Map、Enum、泛型等。
    • 支持循環引用
    • </ul>

      無依賴

      • 不需要例外額外的jar,能夠直接跑在JDK上。
      • </ul>

        支持范圍廣

        • 支持JDK 5、JDK 6、Android、阿里云手機等環境。
        • </ul>

          開源

          • Apache License 2.0
          • 代碼托管在github.org上,項目地址是 https://github.com/AlibabaTech/fastjson
          • </ul>

            測試充分

            • fastjson有超過1500個testcase,每次構建都會跑一遍,豐富的測試場景保證了功能穩定。
            • </ul>

              獲得fastjson

              下載

              http://code.alibabatech.com/mvn/releases/com/alibaba/fastjson/

              maven

              如果你使用了Maven,maven repository配置如下:

              <repository>
                  <id>opensesame</id>
                  <name>Alibaba OpenSource Repsoitory</name>
                  <url>http://code.alibabatech.com/mvn/releases/</url>
                  <snapshots>
                      <enabled>false</enabled>
                  </snapshots>
              </repository>

              pom.xml文件中加入依賴依賴:

              <dependency>
                  <groupId>com.alibaba</groupId>
                  <artifactId>fastjson</artifactId>
                  <version>1.1.14</version>
              </dependency>

              序列化

              一個JSON庫涉及的最基本功能就是序列化和反序列化。Fastjson支持java bean的直接序列化。你可以使用com.alibaba.fastjson.JSON這個類進行序列化和反序列化。

              基本序列化

              序列化就是把JavaBean對象轉化成JSON格式的文本。

              Object o = ...;
              String text = JSON.toJSONString(o);

              在這個例子中,調用JSON.toJSONString方法,把對象o轉化為JSON格式的文本。

              使用單引號

              標準的JSON是使用雙引號的,javascript支持使用單引號格式的json文本,fastjson也支持這個特性,打開SerializerFeature.UseSingleQuotes這個特性就可以了了,例如:

              Object o = ...;
              String text = JSON.toJSONString(o, SerializerFeature.UseSingleQuotes);

              fastjson序列化時可以選擇的SerializerFeature有十幾個,你可以按照自己的需要去選擇使用。

              日期格式化

              fastjson直接支持日期類型數據的格式化,包括java.util.Date、java.sql.Date、java.sql.Timestamp、java.sql.Time。

              缺省情況下,fastjson將Date類型序列化為long,這個使得序列化和反序列化的過程不會導致時區問題。如:
              例如:

              longmillis = 1324138987429L;
              Date date = newDate(millis);       
              System.out.println(JSON.toJSONString(date));

              輸出的結果是

              1324138987429

              fastjson還提供了基于格式化輸出的SerializerFeature,例如:

              JSON.toJSONString(date, SerializerFeature.WriteDateUseDateFormat);

              輸出的結果為:

              "2011-12-18 00:23:07"

              你可以指定輸出日期的格式,比如修改為輸出毫秒:

              JSON.toJSONStringWithDateFormat(date,"yyyy-MM-dd HH:mm:ss.SSS");

              輸出的結果為:

              "2011-12-18 00:23:07.429"

              使用WriteClassName特性

              fastjson支持序列化時寫入類型信息,從而使得反序列化時不至于類型信息丟失。例如:

              Color color = Color.RED;
              String text = JSON.toJSONString(color, SerializerFeature.WriteClassName);
              System.out.println(text);

              輸出結果:

              {"@type":"java.awt.Color","r":255,"g":0,"b":0,"alpha":255}

              由于序列化帶了類型信息,使得反序列化時能夠自動進行類型識別,例如:

              String text = ...; // {"@type":"java.awt.Color","r":255,"g":0,"b":0,"alpha":255}
              Color color = (Color) JSON.parse(text);

              瀏覽器和設備兼容

              fastjson缺省的序列化內容,是對序列化結果緊湊做了優化配置,使得序列化之后長度更小,但是這種優化配置是對一些瀏覽器和設備不兼容的。比如說在iphone上兼容emoji(繪文字)。

              JSON.toJSONString(o, SerializerFeature.BrowserCompatible);

              循環引用

              很多場景中,我們需要序列化的對象中存在循環引用,在許多的json庫中,這會導致stackoverflow。在功能強大的fastjson中,你不需要擔心這個問題。例如:

              A a = newA();
              B b = newB(a);
              a.setB(b);
               
              String text = JSON.toJSONString(a); // {"b":{"a":{"$ref":".."}}}
              A a1 = JSON.parseObject(text, A.class);
              Assert.assertTrue(a1 == a1.getB().getA());

              引用是通過"$ref"來表示的

              引用 描述
              "$ref":".." 上一級
              "$ref":"@" 當前對象,也就是自引用
              "$ref":"$" 根對象
              "$ref":"$.children.0" 基于路徑的引用,相當于 root.getChildren().get(0)

              使用@JSONField Annotation

              在某些場景,你可能需要定制序列化輸出,比如說,希望序列化采用之后采用"ID",而不是"id",你可以使用@JSONField這個Annotation。

              publicclass User {
                  @JSONField(name="ID")
                  publicint getId() { ... }
              }
               
              User user = ...;
              JSON.toJSONString(user);// {"ID":234}

              從json-lib中升級

              如果你已經使用了json-lib,并且痛恨他蝸牛般的速度和羅嗦的API,建議你升級為fastjson,fastjson可以完全兼容json-lib的序列化格式。

              importcom.alibaba.fastjson.JSON;
              importcom.alibaba.fastjson.serializer.JSONLibDataFormatSerializer;
              importcom.alibaba.fastjson.serializer.JSONSerializerMap;
              importcom.alibaba.fastjson.serializer.SerializerFeature;
                
              privatestatic final SerializeConfig   config;
              static{
                  config = newSerializeConfig();
                  config.put(java.util.Date.class,newJSONLibDataFormatSerializer());// 使用和json-lib兼容的日期輸出格式
                  config.put(java.sql.Date.class,newJSONLibDataFormatSerializer());// 使用和json-lib兼容的日期輸出格式
              }
                
              privatestatic final SerializerFeature[] features = { SerializerFeature.WriteMapNullValue, // 輸出空置字段
                      SerializerFeature.WriteNullListAsEmpty,// list字段如果為null,輸出為[],而不是null
                      SerializerFeature.WriteNullNumberAsZero,// 數值字段如果為null,輸出為0,而不是null
                      SerializerFeature.WriteNullBooleanAsFalse,// Boolean字段如果為null,輸出為false,而不是null
                      SerializerFeature.WriteNullStringAsEmpty// 字符類型字段如果為null,輸出為"",而不是null
                                                                };
                
              // 序列化為和JSON-LIB兼容的字符串
              publicstatic String toCompatibleJSONString(Object object) {
                  returnJSON.toJSONString(object, config, features);
              }

              通過上面代碼中的toCompatibleJSONString方法,你就可以實現完全兼容json-lib了。

              反序列化

              反序列化就是把JSON格式的文本轉化為Java Bean對象。

              指定Class信息反序列化

              通過指定類型信息,可以很方便的將"JSON文本"反序列化為"Java Bean"對象,例如:

              String text = ...; // {"r":255,"g":0,"b":0,"alpha":255}
              Color color = JSON.parseObject(text, Color.class);

              類型集合的反序列化

              這個接口類似于parseObject

              String text = ...; // [{ ... }, { ... }]
              List<User> users = JSON.parseArray(text, User.class);

              泛型的反序列化

              如果你需要返回一個帶泛型的對象,例如List<User>、Map<String, User>,你可以使用TypeReference來傳入類型信息。

              String text = ...; // {"name":{"name":"ljw",age:18}}
              Map<String, User> userMap = JSON.parseObject(text, newTypeReference<Map<String, User>>() {});

              組合類型集合的反序列化

              比如在網絡協議中,經常會存在這樣的組合:

              [{/*header*/}, {/*body*/}]

              fastjson對這種結構的反序列化有專門支持。

              String text = ...; // [{/* header */}, {/* body */}]
              Type[] types = newType[] {Header.class, Body.class};
              List<Object> list = JSON.parseArray(text, types);
              Header header = (Header) list.get(0);
              Body body = (Body) list.get(1);

              使用@JSONCreator來指定構造函數來創建對象

              如果你的JavaBean沒有缺省構造函數,可以使用@JSONCreator來指定構造函數

              publicstatic class Entity {
                  privatefinal int    id;
                  privatefinal String name;
               
                  @JSONCreator
                  publicEntity(@JSONField(name = "id")intid,@JSONField(name = "name") String name){
                      this.id = id;
                      this.name = name;
                  }
               
                  publicint getId() { returnid; }
                  publicString getName() { returnname; }
              }

              把JSON文本反序列化為一個原型接口

              publicstatic interface Bean {
                  intgetId();
               
                  voidsetId(intvalue);
               
                  String getName();
               
                  voidsetName(String value);
              }
               
              String text = "{\"id\":123, \"name\":\"chris\"}";
              Bean bean = JSON.parseObject(text, Bean.class);
               
              // 按接口調用
              Assert.assertEquals(123, bean.getId());
              Assert.assertEquals("chris", bean.getName());
              bean.setId(234);
              Assert.assertEquals(234, bean.getId());










              出自:

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!