Json是一種數據格式,便於數據傳輸、存儲、交換;
Gson是一種組件庫,能夠把java對象數據轉換成json數據格式。html
gson.jar的下載地址:http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22gson%22java
1、Json數據樣式android
爲了便於理解咱們先來看看Json的數據樣式:web
1. 單個數據對象json
{ "id": 100, "body": "It is my post", "number": 0.13, "created_at": "2014-05-22 19:12:38" }
2. 多組數據數組
這是一組Json數據,能夠看到就像數組同樣,一組數據是用[]圍起來的,內部{}圍起來的就是單個的數據對象maven
[{ "id": 100, "body": "It is my post1", "number": 0.13, "created_at": "2014-05-20 19:12:38" }, { "id": 101, "body": "It is my post2", "number": 0.14, "created_at": "2014-05-22 19:12:38" }]
3. 嵌套數據函數
這段數據是用{}圍起來的因此是單個數據對象,咱們又能發現其內部又是一個數據對象,名字叫foo2.這就是嵌套的Json數據post
{ "id": 100, "body": "It is my post", "number": 0.13, "created_at": "2014-05-22 19:12:38", "foo2": { "id": 200, "name": "haha" } }
2、經過JsonReader解析Json數據ui
2.1 數據
String jsonData = "[{\"username\":\"name01\",\"userId\":001},{\"username\":\"name02\",\"userId\":002}]";
通常的Json都是從網上獲取的,這裏爲了簡單將Json數據直接用String定義。由於該數據中有各類標點符號,因此要用轉譯。
2.2 解析
/** * @description 經過JsonReader解析Json對象 * * @web http://codego.net/480737/ */ private void jsonReaderTest() { // 這裏的Json放到string中,因此加上了轉譯 String jsonData = "[{\"username\":\"name01\",\"userId\":001},{\"username\":\"name02\",\"userId\":002}]"; JsonReader reader = new JsonReader(new StringReader(jsonData)); reader.setLenient(true); // 在寬鬆模式下解析 try { reader.beginArray(); // 開始解析數組(包含一個或多個Json對象) while (reader.hasNext()) { // 若是有下一個數據就繼續解析 reader.beginObject(); // 開始解析一個新的對象 while (reader.hasNext()) { String tagName = reader.nextName(); // 獲得下一個屬性名 if (tagName.equals("username")) { System.out.println(reader.nextString()); } else if (tagName.equals("userId")) { System.out.println(reader.nextString()); } } reader.endObject(); // 結束對象的解析 } reader.endArray(); // 結束解析當前數組 } catch (IOException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } }
在JsonReader的構造函數中傳入json data,而後開始解析,判斷是否還有下一個對象,若是有就開始解析對象名和對象體,直到解析完畢。
3、經過Gson解析單個Json對象
3.1 數據
assets/Json01
{ "id": 100, "body": "It is my post", "number": 0.13, "created_at": "2014-05-22 19:12:38" }
3.2 載入數據
由於這個數據是定義在本地的,因此要先加載到內存中。方法是經過getAssets()獲得AssetManager對象,再經過open(文件名)來得到文件流。這裏由於我能確保本地的文件小於1m,因此就沒作循環讀取,實際中請務必用循環讀取的方式。最終獲得的數據存放在strData中。
/** * @description 經過assets文件獲取json數據,這裏寫的十分簡單,沒作循環判斷。 * * @return Json數據(String) */ private String getStrFromAssets(String name) { String strData = null; try { InputStream inputStream = getAssets().open(name); byte buf[] = new byte[1024]; inputStream.read(buf); strData = new String(buf); strData = strData.trim(); } catch (IOException e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); } System.out.println("strData = " + strData); return strData; }
3.3 創建類
首先,咱們要根據數據的格式定義一個類
public class Foo01 { public int id; public String body; public float number; public String created_at; }
這個類的定義方式有講究:
1>類裏面的成員變量名必須跟Json字段裏面的name是如出一轍的:
"id": 100, ---- public int id;
2>若是Json數據是嵌套定義的,那麼這個類中就的成員變量確定有個類對象,通常這個類包含內部類
{ "id": 100, "body": "It is my post", "number": 0.13, "created_at": "2014-05-22 19:12:38", "childFoo": { "id": 200, "name": "jack" } }
public class Foo02 { private int id; private String body; private float number; @SerializedName("created_at") private Date createdAt; // 經過註釋的方式更換名字,同時保證使用方式不變。 }
3.4 開始解析
/** * @description 將json數據解析爲類對象 */ private void GsonTest01() { Foo01 foo = new Gson().fromJson(getStrFromAssets("Json01"), Foo01.class); System.out.println("id = " + foo.id); }
3.5 結果
4、經過Gson將數據轉換爲Date對象,而且重命名
4.1 數據
本例的數據和上面徹底同樣,是單個的Json數據
{ "id": 100, "body": "It is my post", "number": 0.13, "created_at": "2014-05-22 19:12:38" }
咱們能夠明顯的發現,最後的創建日期是一個date對象,但經過通常的解析方式,咱們只能把日期數據賦值給string,但之後的操做就很麻煩了。所以,咱們用到了gsonBuilder。gsonBuilder能夠經過檢查json數據的格式,講符合用戶設置格式的數據變爲相應的對象,下面就來演示一下。
4.2 解析
解析仍是兩步,首先定義一個類:
public class Foo02 { private int id; private String body; private float number; @SerializedName("created_at") private Date createdAt; // 經過註釋的方式更換名字,同時保證使用方式不變。 public String get_my_date() { return createdAt.toString(); } }
而後,經過gson解析:
/** * @description 當json中有日期對象時,經過定義構建格式生成須要的date對象 * 當json數據命名和java命名產生不一致時,能夠經過註釋的方式實現更換名字,更方便進行代碼處理 */ private void GsonTest02() { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss"); // 設置日期的格式,遇到這個格式的數據轉爲Date對象 Gson gson = gsonBuilder.create(); Foo02 foo = gson.fromJson(getStrFromAssets("Json01"), Foo02.class); System.out.println("date = " + foo.get_my_date()); }
分析:初始化GsonBuilder後,經過setDateFormat來設置什麼樣的數據會變爲date對象,由於原始數據中created_at的日期格式是yyyy-mm-dd HH:mm:ss因此就寫了以下的代碼:
gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss"); // 設置日期的格式,遇到這個格式的數據轉爲Date對象
以後再經過gsonBuilder的create來創建gson對象,而後解析便可。
4.3 重命名
有時候json的對象名不符合java命名規則,好比這個created_at就沒采用駝峯命名法,但java代碼中推薦用駝峯命名,這樣就產生了矛盾,雖然能夠用別的方式來解決,但咱們還但願用代碼在不影響解析的狀況下,產生符合java命名規則的成員變量。實現也至關簡單,用註釋。
public class Foo02 { private int id; private String body; private float number; @SerializedName("created_at") private Date createdAt; // 經過註釋的方式更換名字,同時保證使用方式不變。 public String get_my_date() { // 能夠經過simpleDateFormat指定data對象的輸出格式,注意:若是要添加自定義字符串,好比下面的custom,必須在字符串兩邊加單引號。 SimpleDateFormat dateFormat = new SimpleDateFormat("'custom'_yyyyMMdd_HHmmss"); //return dateFormat.format(created_at); return createdAt.toString(); } }
在創建Date對象時,咱們在上面加上了換名設定,這樣gson解析時會根據created_at來初始化這個date對象,而咱們使用的時候用craetedAt就能夠了。這裏順便提一下,若是你要輸出date,能夠經過simpleDtaeFormat來設置輸出的格式,這點在設置照片名或文件名時頗有用。固然,若是你沒這個需求,你徹底能夠用toString()方法。
4.4 結果
能夠看見,這裏的date對象是按照標準的格式進行顯示的,說明解析成功!
5、解析嵌套的Json數據
5.1數據
{ "id": 100, "body": "It is my post", "number": 0.13, "created_at": "2014-05-22 19:12:38", "childFoo": { "id": 200, "name": "jack" } }
先來分析下數據,這是一個單個數據,裏面嵌套了一個childFoo。那麼構建類的時候就須要有兩個類,一個類包含id,body,number,created_at,childFoo.另外一個類中包含id,name。
5.2 構建類
這裏爲了簡單,把兩個類合二爲一了。注意下這個內部類其實能夠不叫ChildFoo的,只要這個類產生的對象的名字叫作childFoo就行(區分大小寫)。
package com.kale.gsontest; /** * @author:Jack Tony * @description : 針對有嵌套的json數據 * @date :2015年1月24日 */ public class Foo03 { public int id; public String body; public float number; public String created_at; public ChildFoo childFoo; public class ChildFoo { public int id; public String name; } }
5.3 解析
/** * @description 解析嵌套是Json數據 * */ private void GsonTest03() { Foo03 foo = new Gson().fromJson(getStrFromAssets("Json02"), Foo03.class); System.out.println("name = " + foo.childFoo.name); }
爲了看是否解析成功,這裏直接輸出類中內部類的成員變量:name
5.4 結果
能夠看見,輸出了childFoo中的name值:jack
6、將Json序列解析爲數組
6.1 數據
[{ "id": 100, "body": "It is my post1", "number": 0.13, "created_at": "2014-05-20 19:12:38" }, { "id": 101, "body": "It is my post2", "number": 0.14, "created_at": "2014-05-22 19:12:38" }]
一般狀況下Json數據包含多個對象,若是不包含多個對象的狀況比較少見。舉個例子:
http://m.weather.com.cn/data/101010100.html
{"weatherinfo":{"city":"北京","city_en":"beijing","date_y":"2014年3月4日","date":"","week":"星期二","fchh":"11","cityid":"101010100","temp1":"8℃~-3℃","temp2":"8℃~-3℃","temp3":"7℃~-3℃","temp4":"8℃~-1℃","temp5":"10℃~1℃","temp6":"10℃~2℃","tempF1":"46.4℉~26.6℉","tempF2":"46.4℉~26.6℉","tempF3":"44.6℉~26.6℉","tempF4":"46.4℉~30.2℉","tempF5":"50℉~33.8℉","tempF6":"50℉~35.6℉","weather1":"晴","weather2":"晴","weather3":"晴","weather4":"晴轉多雲","weather5":"多雲","weather6":"多雲","img1":"0","img2":"99","img3":"0","img4":"99","img5":"0","img6":"99","img7":"0","img8":"1","img9":"1","img10":"99","img11":"1","img12":"99","img_single":"0","img_title1":"晴","img_title2":"晴","img_title3":"晴","img_title4":"晴","img_title5":"晴","img_title6":"晴","img_title7":"晴","img_title8":"多雲","img_title9":"多雲","img_title10":"多雲","img_title11":"多雲","img_title12":"多雲","img_title_single":"晴","wind1":"北風4-5級轉微風","wind2":"微風","wind3":"微風","wind4":"微風","wind5":"微風","wind6":"微風","fx1":"北風","fx2":"微風","fl1":"4-5級轉小於3級","fl2":"小於3級","fl3":"小於3級","fl4":"小於3級","fl5":"小於3級","fl6":"小於3級","index":"寒冷","index_d":"天氣寒冷,建議着厚羽絨服、毛皮大衣加厚毛衣等隆冬服裝。年老體弱者尤爲要注意保暖防凍。","index48":"冷","index48_d":"天氣冷,建議着棉服、羽絨服、皮夾克加羊毛衫等冬季服裝。年老體弱者宜着厚棉衣、冬大衣或厚羽絨服。","index_uv":"中等","index48_uv":"中等","index_xc":"較適宜","index_tr":"通常","index_co":"較溫馨","st1":"7","st2":"-3","st3":"8","st4":"0","st5":"7","st6":"-1","index_cl":"較不宜","index_ls":"基本適宜","index_ag":"易發"}}
如今咱們想把這多個對象解析爲一個數組對象,應該怎麼作呢?
6.2 創建類
十分簡單,包含一個對象中的信息便可。順便一提,若是你不須要解析那麼多結果,你能夠僅僅列出你想要解析的變量。
public class Foo01 { public int id; public String body; public float number; public String created_at; }
6.3 解析
/** * @description 解析爲數組 * */ private void GsonTest04() { Foo01[] foos = new Gson().fromJson(getStrFromAssets("Json03"), Foo01[].class); System.out.println("name01 = " + foos[0].id); System.out.println("name02 = " + foos[1].id); // 這時候想轉成List的話調用以下方法 // List<Foo> foosList = Arrays.asList(foos); }
gson的構造函數提供瞭解析成數組對象的方法,因此直接像解析單個對象同樣使用就行。
6.4 結果
7、將數據解析爲list
7.1 數據
這個數據和上面徹底同樣
[{ "id": 100, "body": "It is my post1", "number": 0.13, "created_at": "2014-05-20 19:12:38" }, { "id": 101, "body": "It is my post2", "number": 0.14, "created_at": "2014-05-22 19:12:38" }]
7.2 創建類
類也和上面的同樣,沒任何變化
package com.kale.gsontest; public class Foo01 { public int id; public String body; public float number; public String created_at; }
7.3 解析
/** * @description 將json序列變爲list對象 * */ private void GsonTest05() { Type listType = new TypeToken<ArrayList<Foo01>>(){}.getType();
ArrayList<Foo01> foos = new Gson().fromJson(getStrFromAssets("Json03"), listType); for (int i = 0; i < foos.size(); i++) { System.out.println("name ["+ i +"] = " + foos.get(i).id); } }
這裏不一樣的一點就是要定義list的類型,其他的沒什麼可說的。通常咱們都會用這種方式將數據放到list中,不多會用到解析成數組。
7.4 結果
源碼下載:http://download.csdn.net/detail/shark0017/8393351
參考自:
http://stormzhang.com/android/2014/05/22/android-gson/
http://www.cnblogs.com/jxgxy/p/3677256.html
http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22gson%22