JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。它基于ECMAScript的一個(gè)子集。 JSON采用完全獨(dú)立于語(yǔ)言的文本格式,但是也使用了類似于C語(yǔ)言家族的習(xí)慣(包括C蚓曼、C++脉执、C#踢代、Java盲憎、JavaScript、Perl胳挎、Python等)饼疙。這些特性使JSON成為理想的數(shù)據(jù)交換語(yǔ)言。 易于人閱讀和編寫慕爬,同時(shí)也易于機(jī)器解析和生成(一般用于提升網(wǎng)絡(luò)傳輸速率)窑眯。
Android開發(fā)基本遵從MVC模式。由于JSON的種種優(yōu)良特性医窿,使得大部分Model都從JSON轉(zhuǎn)換而來(lái)磅甩。于是把 JSON轉(zhuǎn)為對(duì)應(yīng)的JavaModel 就成移動(dòng)端開發(fā)工作很常規(guī)的一部分。
這個(gè)工作的輸入輸出很明確:
輸入 是一個(gè)json的字符串
{
"type":"object",
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "integer"
},
"baz": {
"type": "boolean"
}
}
}
輸出 是對(duì)應(yīng)的一系列java類:
public class DataModel extends BaseModel {
private String type;
private PropertiesBean properties;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public PropertiesBean getProperties() {
return properties;
}
public void setProperties(PropertiesBean properties) {
this.properties = properties;
}
}
public static class PropertiesBean {
private FooBean foo;
private BarBean bar;
private BazBean baz;
public FooBean getFoo() {
return foo;
}
public void setFoo(FooBean foo) {
this.foo = foo;
}
public BarBean getBar() {
return bar;
}
public void setBar(BarBean bar) {
this.bar = bar;
}
public BazBean getBaz() {
return baz;
}
public void setBaz(BazBean baz) {
this.baz = baz;
}
}
public static class FooBean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public static class BarBean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public static class BazBean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
怎么完成這個(gè)轉(zhuǎn)化過(guò)程呢姥卢?
轉(zhuǎn)化方式一:復(fù)制粘貼卷要、手動(dòng)修正(最原始!6懒瘛)
對(duì)著原始的json串僧叉,把名字復(fù)制過(guò)來(lái),手動(dòng)設(shè)置每個(gè)json項(xiàng)的類型棺榔。這種方式的缺點(diǎn)非常明顯:
- 耗時(shí)長(zhǎng)
- 人工操作太多瓶堕,容易出錯(cuò),萬(wàn)一手誤把名字復(fù)制錯(cuò)了症歇,后期排除錯(cuò)誤的過(guò)程也比較麻煩郎笆。
轉(zhuǎn)化方式二:使用GsonFormat智能轉(zhuǎn)JSON
GsonFormat應(yīng)該是Android Studio上必備插件之一,先來(lái)看效果圖
效果非常的贊忘晤,而且支持過(guò)濾父類已有屬性宛蚓,這樣就不用在繼承父類后還要?jiǎng)h除相同的屬性了。它的安裝和使用方法也非常簡(jiǎn)單方便德频,具體方式參考其github主頁(yè):https://github.com/zzz40500/GsonFormat
類似插件還有一個(gè)苍息,叫JsonModelGenerator缩幸,其支持將類型為 JSONObject 和 JSONArray 的子元素拆分為單獨(dú)的實(shí)體類壹置。不過(guò)它用起來(lái)比較繁瑣,必須透過(guò)url獲取原始json串表谊,不推薦使用钞护。
由于GsonFormat的使用方式僅限于單個(gè)java類內(nèi),所以它解析產(chǎn)生的子類都是內(nèi)嵌類爆办,所以還是會(huì)需要手動(dòng)調(diào)整類的繼承關(guān)系难咕。另外每個(gè)JSON串都要先新建再轉(zhuǎn)JSON的時(shí)候,當(dāng)JSON串比較多的時(shí)候,就會(huì)覺得這一步也挺繁瑣的(程序員就是懶啊~)余佃,有沒有批量轉(zhuǎn)json的方式呢暮刃?
轉(zhuǎn)化方式三:使用JsonAnnotation批量轉(zhuǎn)JSON
JsonAnnotation利用了java annotation的特性,在Android編譯時(shí)將如下格式的代碼
String simpleStr = "{\n"
+ " \"id\": 100,\n"
+ " \"body\": \"It is my post\",\n"
+ " \"number\": 0.13,\n"
+ " \"created_at\": \"2014-05-22 19:12:38\"\n"
+ "}";
// 簡(jiǎn)單格式
@Json2Model(modelName = "SimpleModel", jsonStr = simpleStr)
String TEST_SIMPLE = "test/simple"; // api url
轉(zhuǎn)化為test.simple包下的一個(gè)類SimpleModel爆土,代碼如下:
package test.simple;
import com.google.gson.annotations.SerializedName;
public class SimpleModel {
@SerializedName("id")
private int id;
@SerializedName("body")
private String body;
@SerializedName("created_at")
private String createdAt;
@SerializedName("number")
private double number;
public void setId(int id) {
this.id = id;
}
public void setBody(String body) {
this.body = body;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public void setNumber(double number) {
this.number = number;
}
public int getId() {
return id;
}
public String getBody() {
return body;
}
public String getCreatedAt() {
return createdAt;
}
public double getNumber() {
return number;
}
}
這樣就可以批量將json轉(zhuǎn)成Model了椭懊,而且由于其只在編譯時(shí)起作用,所以并不影響程序運(yùn)行時(shí)的性能(非常棒的~)步势。具體使用方法參考其github主頁(yè):https://github.com/tianzhijiexian/JsonAnnotation
不過(guò)這種方式還是有不便利的地方氧猬,主要體現(xiàn)在兩個(gè)地方:
- 沒有辦法指定json對(duì)應(yīng)類的父類,因此如果Model之間有繼承關(guān)系坏瘩,需要手動(dòng)處理
- 不會(huì)智能判斷不同json串之間的關(guān)聯(lián)關(guān)系盅抚,因此如果Model之間有組合關(guān)系,需要手動(dòng)處理倔矾。
轉(zhuǎn)化方式四:脫離Android Studio環(huán)境轉(zhuǎn)JSON
方式三和四都基于Android Studio這個(gè)開發(fā)環(huán)境妄均,有沒有脫離這個(gè)環(huán)境直接將JSON串轉(zhuǎn)成Java Model的方式呢?
有破讨。
點(diǎn)開http://www.jsonschema2pojo.org/網(wǎng)站丛晦,可以看到如下界面:
操作很直觀清晰,可以直接將JSON轉(zhuǎn)為Model提陶,而且支持預(yù)覽烫沙,其產(chǎn)物為一系列java文件(因?yàn)閮?nèi)嵌的json對(duì)象會(huì)被解析為獨(dú)立java類)。
類似網(wǎng)站有JSON To Java
注意:這兩個(gè)網(wǎng)站都不支持批量轉(zhuǎn)JSON隙笆。
以上就是目前搜集到的所有可用資源了锌蓄,它們都是GitHub上的開源項(xiàng)目,相關(guān)地址如下:
目前最佳實(shí)踐清單
從目前來(lái)撑柔,最佳方式是綜合JsonAnnotation
和GsonFormat
瘸爽。
- 首先利用JsonAnnotation批量生成所有的java類。
- 然后根據(jù)其中的組合铅忿、繼承關(guān)系進(jìn)行人工修正剪决。
- 當(dāng)遇到參數(shù)增刪較多的時(shí)候,用GsonFormat進(jìn)行單個(gè)操作檀训。
PS:JsonAnnotation 這個(gè)項(xiàng)目真不錯(cuò)柑潦,如果能把繼承和組合關(guān)系也解決掉,它就完美了~~
拓展閱讀:
Panda
2016-07-06