Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 一個現代化的JSON庫Moshi針對Android和Java,jsonandroid

一個現代化的JSON庫Moshi針對Android和Java,jsonandroid

編輯:關於android開發

一個現代化的JSON庫Moshi針對Android和Java,jsonandroid


Moshi

是一個現代化的JSON庫針對Android和Java。它可以很容易地解析JSON成Java對象:


String json = ...;

Moshi moshi = new Moshi.Builder().build();
JsonAdapter<BlackjackHand> jsonAdapter = moshi.adapter(BlackjackHand.class);

BlackjackHand blackjackHand = jsonAdapter.fromJson(json);
System.out.println(blackjackHand);

它可以很容易地Java對象序列為JSON:


BlackjackHand blackjackHand = new BlackjackHand(
    new Card('6', SPADES),
    Arrays.asList(new Card('4', CLUBS), new Card('A', HEARTS)));

Moshi moshi = new Moshi.Builder().build();
JsonAdapter<BlackjackHand> jsonAdapter = moshi.adapter(BlackjackHand.class);

String json = jsonAdapter.toJson(blackjackHand);
System.out.println(json);

內置型適配器

莫西已經內置了支持讀取和寫入Java的核心數據類型:

  • 原語(整型,浮點,焦炭......)及其同行盒裝(整數,浮點數,字符...)。
  • 數組,集合,列表,集合和地圖
  • 字符串
  • 枚舉

它通過寫出來場逐場支持你的模型類。在上面的莫希例子使用這些類:


class BlackjackHand {
  public final Card hidden_card;
  public final List<Card> visible_cards;
  ...
}

class Card {
  public final char rank;
  public final Suit suit;
  ...
}

enum Suit {
  CLUBS, DIAMONDS, HEARTS, SPADES;
}

讀寫此JSON:


{
  "hidden_card": {
    "rank": "6",
    "suit": "SPADES"
  },
  "visible_cards": [
    {
      "rank": "4",
      "suit": "CLUBS"
    },
    {
      "rank": "A",
      "suit": "HEARTS"
    }
  ]
}

該Javadoc中編目完整的莫西API,我們將在下面探討。

自定義類型的適配器

隨著磨石,這是特別容易定制值的轉換方式,並從JSON。A型適配器是有注釋的方法,任何類@ToJson@FromJson

例如,磨石的一張撲克牌的默認編碼為詳細:JSON的定義在不同領域的點數和花色:{“等級”:“A”,“套裝”:“心”}。隨著類型的適配器,我們可以改變編碼的東西更緊湊:“4H”為心中的四,“JD”為鑽石插孔:


class CardAdapter {
  @ToJson String toJson(Card card) {
    return card.rank + card.suit.name().substring(0, 1);
  }

  @FromJson Card fromJson(String card) {
    if (card.length() != 2) throw new JsonDataException("Unknown card: " + card);

    char rank = card.charAt(0);
    switch (card.charAt(1)) {
      case 'C': return new Card(rank, Suit.CLUBS);
      case 'D': return new Card(rank, Suit.DIAMONDS);
      case 'H': return new Card(rank, Suit.HEARTS);
      case 'S': return new Card(rank, Suit.SPADES);
      default: throw new JsonDataException("unknown suit: " + card);
    }
  }
}

注冊與該類型的適配器Moshi.Builder,我們是好去。



Moshi moshi = new Moshi.Builder()
    .add(new CardAdapter())
    .build();

Voila:

{
  "hidden_card": "6S",
  "visible_cards": [
    "4C",
    "AH"
  ]
}

另一個安卓源碼例子

需要注意的是帶注釋方法@FromJson並不需要采取一個字符串作為參數。相反,它可以采取任何類型的輸入和磨石將首先解析JSON到該類型的對象,然後使用@FromJson方法以產生所需的最終值。相反,帶注釋的方法@ToJson沒有產生一個字符串。

假設,例如,我們必須分析,其中一個事件的日期和時間被表示為兩個獨立的字符串一個JSON。


{
  "title": "Blackjack tournament",
  "begin_date": "20151010",
  "begin_time": "17:04"
}

我們想這兩個字段合並為一個串,以方便的時間在稍後分析。同時,我們希望有首字母大寫的所有變量名。因此,事件 我們要莫希產生這樣的類:


class Event {
  String title;
  String beginDateAndTime;
}

不用手動解析每行的JSON行(我們也可以做到),我們可以有莫希自動完成改造。我們簡單地定義另一個類EventJson直接對應於JSON結構:


class EventJson {
  String title;
  String begin_date;
  String begin_time;
}

並用適當的另一個類@FromJson@ToJson被告知莫希如何將一個轉換方法EventJson一個事件和背部。現在,每當我們要求莫希分析一個JSON到一個事件,將首先將其解析到一個EventJson作為一個中間步驟。相反,序列化一個事件莫希將首先創建一個EventJson對象,然後序列化對象如常。


class EventJsonAdapter {
  @FromJson Event eventFromJson(EventJson eventJson) {
    Event event = new Event();
    event.title = eventJson.title;
    event.beginDateAndTime = eventJson.begin_date + " " + eventJson.begin_time;
    return event;
  }

  @ToJson EventJson eventToJson(Event event) {
    EventJson json = new EventJson();
    json.title = event.title;
    json.begin_date = event.beginDateAndTime.substring(0, 8);
    json.begin_time = event.beginDateAndTime.substring(9, 14);
    return json;
  }
}

我們再次注冊莫希適配器。


Moshi moshi = new Moshi.Builder()
    .add(new EventJsonAdapter())
    .build();

現在我們可以用磨石直接解析JSON到一個事件


JsonAdapter<Event> jsonAdapter = moshi.adapter(Event.class);
Event event = jsonAdapter.fromJson(json);

優雅地失敗

自動數據綁定幾乎感覺像魔術。但不同的是黑魔法,通常伴隨著反射,磨石旨在幫助你當事情出錯。


JsonDataException: Expected one of [CLUBS, DIAMONDS, HEARTS, SPADES] but was ANCHOR at path $.visible_cards[2].suit
  at com.squareup.moshi.JsonAdapters$11.fromJson(JsonAdapters.java:188)
  at com.squareup.moshi.JsonAdapters$11.fromJson(JsonAdapters.java:180)
    ...

莫希總是拋出一個標准的java.io.IOException異常,如果有一個錯誤讀取JSON文檔,或者如果它是畸形的。它拋出一個JsonDataException如果JSON文件是良好的,但不符合預期的格式。

建立在奧基奧

莫希使用奧基奧簡單而功能強大的I / O。這是一個很好的補充,OkHttp,它可以共享緩沖段的最大效率。

從GSON借用

莫希使用相同的流媒體和約束機制為GSON。如果你是一個GSON用戶,你會發現莫希工作方式類似。如果您嘗試莫希和不愛它,你甚至可以遷移到GSON沒有太多的暴力!

但是,這兩個庫有幾個重要的區別:

  • 莫希具有較少的內置類型的適配器。例如,您需要配置自己的日期適配器。大多數綁定庫將編碼不管你扔他們。莫希拒絕序列化的平台類型(java中。*使用javax。*,和Android系統。*)無用戶提供類型的適配器。這是為了防止意外鎖定自己特定的JDK或Android版 本。
  • 莫希較少配置的。有沒有現場的命名策略,版本控制,例如創作者,或長系列化策略。相反,命名字段visibleCards和使用策略類將其轉換成visible_cards,磨石要你只是名稱的字段visible_cards,因為它出現在JSON。
  • 莫希沒有一個JsonElement模式。相反,它只是使用內置的類型,如列表和 地圖
  • 沒有HTML安全轉義。 GSON編碼=\ u003d默認情況下,以便它可以在HTML中被安全編碼,無需額外轉義。莫希自然編碼它(如=),並假定HTML編碼器-如果有的話-會做自己的工作。

與@Json自定義字段名稱

莫希最適合當你的JSON對象和Java對象具有相同的結構。但是,當他們不這樣做,磨石有注釋定制數據綁定。

使用@Json指定的Java如何字段映射到JSON的名字。這是必要的,當JSON名稱包含空格或者未在Java字段名稱中不允許其他字符。例如,這個JSON有包含空格的字段名稱:


{
  "username": "jesse",
  "lucky number": 32
}

隨著@Json其相應的Java類很簡單:


class Player {
  String username;
  @Json(name = "lucky number") int luckyNumber;

  ...
}

由於JSON字段名始終與他們的Java領域的定義,磨石使得Java和JSON之間航行時很容易找到的字段。

與@JsonQualifier交替類型的適配器

使用@JsonQualifier自定義類型是如何編碼的某些字段,而不無處不在改變其編碼。這種工作方式類似於在預選賽中的注釋依賴注入工具,如匕首和吉斯。

下面是兩個整數和顏色的JSON消息:


{
  "width": 1024,
  "height": 768,
  "color": "#ff0000"
}

按照慣例,Android的程序也使用INT的顏色:


class Rectangle {
  int width;
  int height;
  int color;
}

但是,如果我們編碼上面的Java類JSON,顏色不正確編碼!


{
  "width": 1024,
  "height": 768,
  "color": 16711680
}

解決方法是定義一個限定注解,注解本身@JsonQualifier


@Retention(RUNTIME)
@JsonQualifier
public @interface HexColor {
}

下一步將此@HexColor注釋相應字段:


class Rectangle {
  int width;
  int height;
  @HexColor int color;
}

最後定義一個類型的適配器來處理它:


/** Converts strings like #ff0000 to the corresponding color ints. */
class ColorAdapter {
  @ToJson String toJson(@HexColor int rgb) {
    return String.format("#%06x", rgb);
  }

  @FromJson @HexColor int fromJson(String rgb) {
    return Integer.parseInt(rgb.substring(1), 16);
  }
}

使用@JsonQualifier當您需要為同一型號不同JSON編碼。大部分程序不應該需要這個@JsonQualifier,但它是為那些確實非常方便。

下載

下載最新的JAR或通過Maven的依賴:


<dependency>
  <groupId>com.squareup.moshi</groupId>
  <artifactId>moshi</artifactId>
  <version>1.1.0</version>
</dependency>

or Gradle:

compile 'com.squareup.moshi:moshi:1.1.0'

下載地址https://github.com/square/moshi/archive/master.zip

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved