要创建和解析JSON数据,也可以使用GSON来完成。GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。
使用GSON,可以很容易的将一串JSON数据转换为一个Java对象,或是将一个Java对象转换为相应的JSON数据。
1.GSON的两个重要方法
在GSON的API中,提供了两个重要的方法:toJson()和fromJson()方法。其中,toJson()方法用来实现将Java对象转换为相应的JSON数据,fromJson()方法则用来实现将JSON数据转换为相应的Java对象。
1.1 toJson()方法
toJson()方法用于将Java对象转换为相应的JSON数据,主要有以下几种形式:
(1)String toJson(JsonElement jsonElement);
(2)String toJson(Object src);
(3)String toJson(Object src, Type typeOfSrc);
其中,方法(1)用于将JsonElement对象(可以是JsonObject、JsonArray等)转换成JSON数据;方法(2)用于将指定的Object对象序列化成相应的JSON数据;方法(3)用于将指定的Object对象(可以包括泛型类型)序列化成相应的JSON数据。
1.2 fromJson()方法
fromJson()方法用于将JSON数据转换为相应的Java对象,主要有以下几种形式:
(1)<T> T fromJson(JsonElement json, Class<T> classOfT);
(2)<T> T fromJson(JsonElement json, Type typeOfT);
(3)<T> T fromJson(JsonReader reader, Type typeOfT);
(4)<T> T fromJson(Reader reader, Class<T> classOfT);
(5)<T> T fromJson(Reader reader, Type typeOfT);
(6)<T> T fromJson(String json, Class<T> classOfT);
(7)<T> T fromJson(String json, Type typeOfT);
以上的方法用于将不同形式的JSON数据解析成Java对象。
JSON数据的解析:
解析JSON数据, 首先需要明确待解析的是JSON Object还是JSON array, 然后需要确定采用哪种解析技术.
android平台上一般有2种解析技术可供选择:android内置的org.json包和google的开源gson库.
以下将分别采用这两种技术解析JSON对象和JSON数组来比较学习GSon的使用方法。
1. 采用android内置的org.json包解析JSON对象.
假设待解析的JSON数据为
json = "{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}",
其中\用于转义表达式中的双引号. 首先需要定义2个JavaBean和json对象的数据类型匹配:
- package text.com.bean;
- public class Address {
- private String street;
- private String city;
- private String country;
- public Address() {
- super();
- }
- public Address(String street, String city, String country) {
- super();
- this.street = street;
- this.city = city;
- this.country = country;
- }
- public String getStreet() {
- return street;
- }
- public void setStreet(String street) {
- this.street = street;
- }
- public String getCity() {
- return city;
- }
- public void setCity(String city) {
- this.city = city;
- }
- public String getCountry() {
- return country;
- }
- public void setCountry(String country) {
- this.country = country;
- }
- @Override
- public String toString() {
- return "Address [street=" + street + ", city=" + city + ", country="
- + country + "]";
- }
- }
package text.com.bean;
public class Address {
private String street;
private String city;
private String country;
public Address() {
super();
}
public Address(String street, String city, String country) {
super();
this.street = street;
this.city = city;
this.country = country;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "Address [street=" + street + ", city=" + city + ", country="
+ country + "]";
}
}
- package text.com.bean;
- public class Person {
- private String name;
- private int age;
- private boolean male;
- private Address address;
- public Person() {
- super();
- }
- public Person(String name, int age, boolean male, Address address) {
- super();
- this.name = name;
- this.age = age;
- this.male = male;
- this.address = address;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public boolean isMale() {
- return male;
- }
- public void setMale(boolean male) {
- this.male = male;
- }
- public Address getAddress() {
- return address;
- }
- public void setAddress(Address address) {
- this.address = address;
- }
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + ", male=" + male
- + ", address=" + address + "]";
- }
- }
首先使用方法一(org.json包下的工具类)解析,代码如下:
- JSONObject jsonObject = new JSONObject(json);
- String name = jsonObject.getString("name");
- int age = jsonObject.getInt("age");
- boolean male = jsonObject.getBoolean("male");
- JSONObject addressJSON = jsonObject.getJSONObject("address");
- String street = addressJSON.getString("street");
- String city = addressJSON.getString("city");
- String country = addressJSON.getString("country");
- Address address = new Address(street, city, country);
- Person person = new Person(name, age, male, address);
- System.out.println(person);
JSONObject jsonObject = new JSONObject(json);
String name = jsonObject.getString("name");
int age = jsonObject.getInt("age");
boolean male = jsonObject.getBoolean("male");
JSONObject addressJSON = jsonObject.getJSONObject("address");
String street = addressJSON.getString("street");
String city = addressJSON.getString("city");
String country = addressJSON.getString("country");
Address address = new Address(street, city, country);
Person person = new Person(name, age, male, address);
System.out.println(person);
LogCat的输出为:
Person [name=coolxing, age=24, male=true, address=Address [street=huiLongGuan, city=beijing, country=china]],
说明已经正确解析了JSON对象.
2. 采用GSON库解析JSON对象. 假设待解析的JSON数据是json = "{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}",
首先需要到http://code.google.com/p/google-gson/下载jar包, 并将其添加到项目中. 具体的解析代码如下:
- Gson gson = new Gson();
- Person person = gson.fromJson(json, Person.class);
- System.out.println(person);
Gson gson = new Gson();
Person person = gson.fromJson(json, Person.class);
System.out.println(person);
LogCat的输出为:
Person [name=coolxing, age=24, male=true, address=Address [street=huiLongGuan, city=beijing, country=china]],
说明已经正确解析了JSON对象, 是不是很简单?
3. 采用android内置的org.json包解析JSON数组. 假设待解析的JSON数据为
json = "[{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}, {\"name\":\"min\", \"age\"=20, \"male\":false, \"address\":{\"street\":\"heiShiJiao\", \"city\":\"daLian\", \"country\":\"china\"}}]",
解析代码如下:
-
List<Person> persons = new ArrayList<Person>();
-
JSONArray jsonArray = new JSONArray(json);
- for(int i = 0; i < jsonArray.length(); i++) {
- JSONObject jsonObject = jsonArray.getJSONObject(i);
- String name = jsonObject.getString("name");
- int age = jsonObject.getInt("age");
- boolean male = jsonObject.getBoolean("male");
- JSONObject addressJSON = jsonObject.getJSONObject("address");
- String street = addressJSON.getString("street");
- String city = addressJSON.getString("city");
- String country = addressJSON.getString("country");
- Address address = new Address(street, city, country);
- Person person = new Person(name, age, male, address);
- persons.add(person);
- }
- System.out.println(persons);
4. 采用gson库解析JSON数组. 待解析的JSON数据同上, 具体代码为:
- Gson gson = new Gson();
- Type listType = new TypeToken<List<Person>>(){}.getType();
- List<Person> persons = gson.fromJson(json, listType);
Gson gson = new Gson();
Type listType = new TypeToken<List<Person>>(){}.getType();
List<Person> persons = gson.fromJson(json, listType);
测试用例:
- package text.com;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStreamReader;
- import java.lang.reflect.Type;
- import java.util.List;
- import text.com.bean.Address;
- import text.com.bean.Person;
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
- public class JsonTest {
- String jsonString = "";
- public static void main(String[] args) {
- // Person p1 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",
- // "30号"));
- // Person p2 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",
- // "30号"));
- // Person p3 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",
- // "30号"));
- // List<Person> list = new ArrayList<Person>();
- // list.add(p1);
- // list.add(p2);
- // list.add(p3);
- // Gson gson = new Gson();
- // Type typeOfT = new TypeToken<List<Person>>(){}.getType();
- // String json = gson.toJson(list, typeOfT);
- // System.out.println("json:"+json);
- // String str = readTxtFile("D:\\cjjworkspace\\Test\\json.txt");
- // System.out.println("文件内容:" + str);
- Gson gson = new Gson();
- // Type typeOfT = new TypeToken<List<Person>>(){}.getType();
- // List<Person> personList = gson.fromJson(str, typeOfT);
- Person p1 = new Person("zhangsan", 12, true, new Address("北京", "海淀区", "30号"));
- Type typeOfT = new TypeToken<Person>(){}.getType();
- String str = gson.toJson(p1, typeOfT);
- System.out.println(str);
- }
- public static String readTxtFile(String filePath) {
- String encoding = "utf-8";
- StringBuilder sb = new StringBuilder();
- try {
- File file = new File(filePath);
- if (file.isFile() && file.exists()) { // 判断文件是否存在
- InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
- BufferedReader bufferedReader = new BufferedReader(read);
- String str = "";
- while ((str = bufferedReader.readLine()) != null) {
- sb.append(str);
- }
- read.close();
- return sb.toString();
- } else {
- System.out.println("找不到指定的文件");
- return null;
- }
- } catch (Exception e) {
- System.out.println("读取文件内容出错");
- e.printStackTrace();
- }
- return sb.toString();
- }
- }
通过以上比较,我们可发发现通过GSON解析json数据,相对于org.json方便的多。
以上简单说明是将json数据解析后转化为Java对象,同时,我们也可以通过Gson将Java对象方便的转化为json对象。
例如:
package cn.sunzn.gson; import java.util.ArrayList; import java.util.Collections; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.util.Log; import cn.sunzn.bean.Person; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class GsonActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Gson gson = new Gson(); /** * 将给定的 JSON 字符串转换成指定的类型对象 */ String json = "{\"name\":\"Tom\",\"age\":90}"; Person person = gson.fromJson(json, Person.class); Log.e("GSON", person.toString()); /** * 将给定的目标对象转换成 JSON 格式的字符串 */ String json_Person = gson.toJson(person); Log.e("GSON", json_Person); /** * 将给定的集合对象转换成 JSON 格式的字符串 */ ArrayList<Person> persons = new ArrayList<Person>(); Collections.addAll(persons, new Person("tom", 10), new Person("jon", 20)); String json_list = gson.toJson(persons); Log.e("GSON", json_list); /** * 将给定的 JSON 格式字符串转换为带泛型的集合对象 */ List<Person> retList = gson.fromJson(json_list, new TypeToken<List<Person>>() {}.getType()); for (Person p : retList) { Log.e("GSON", p.toString()); } } }
Gson 解析 Json 运行结果
02-19 07:39:23.467: E/GSON(669): Person [name=Tom, age=90]
02-19 07:39:23.487: E/GSON(669): {"name":"Tom","age":90}
02-19 07:39:23.517: E/GSON(669): [{"name":"tom","age":10},{"name":"jon","age":20}]
02-19 07:39:23.547: E/GSON(669): Person [name=tom, age=10]
02-19 07:39:23.547: E/GSON(669): Person [name=jon, age=20]
Gson 转换过程中使用的实体类 Person
package cn.sunzn.bean; import com.google.gson.annotations.Expose; public class Person { @Expose private String name; @Expose private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
通过GSON解析复杂的json对象实例:
数据格式:
- {
- "data": {
- "partnerteamlist": [
- {
- "pteamId": 72825,
- "ptitle": "随摄影/共6套服装/准爸准妈共拍/免费肚画/底片全送。",
- "pteamprice": 288
- },
- {
- "pteamId": 72598,
- "ptitle": "随摄影/拍摄200张/4本相册/品质拍摄/送全新婚纱。",
- "pteamprice": 2888
- },
- {
- "pteamId": 72613,
- "ptitle": "随摄影/送全新婚纱/多外景拍摄/服装不限数量/绝无二次消费!",
- "pteamprice": 3699
- },
- {
- "pteamId": 72638,
- "ptitle": "随摄影/服装不限数量/高品质拍摄260张/送全新婚纱。",
- "pteamprice": 4299
- },
- {
- "pteamId": 72716,
- "ptitle": "随摄影/3组服装造型/内外景拍摄/完全透明消费!",
- "pteamprice": 388
- }
- ],
- "liketeamlist": [
- {
- "lteamId": 65886,
- "ltitle": "爱丽尔婚纱摄影/2本相册/6套服装造型/拍摄不限最低拍摄150张。",
- "limage": "http://img.pztuan.com/upfile/team/2013/0712/201307120257551465.jpg",
- "lteamprice": 518,
- "lmarketprice": 3999
- },
- {
- "lteamId": 57133,
- "ltitle": "陶冶摄影/婚纱闺蜜/6组服装造型/拍摄不低于120张!",
- "limage": "http://img.pztuan.com/upfile/team/2013/0628/201306281115249737.jpg",
- "lteamprice": 580,
- "lmarketprice": 3380
- }
- ],
- "feedbacks": {
- "feedbacklist": [
- {
- "comment": "5分",
- "createtime": "2014.07.08 13:38",
- "score": 5,
- "username": "l***2"
- }
- ],
- "totalcount": 1,
- "totalscore": 5
- }
- },
- "err": null,
- "state": 1
- }
{
"data": {
"partnerteamlist": [
{
"pteamId": 72825,
"ptitle": "随摄影/共6套服装/准爸准妈共拍/免费肚画/底片全送。",
"pteamprice": 288
},
{
"pteamId": 72598,
"ptitle": "随摄影/拍摄200张/4本相册/品质拍摄/送全新婚纱。",
"pteamprice": 2888
},
{
"pteamId": 72613,
"ptitle": "随摄影/送全新婚纱/多外景拍摄/服装不限数量/绝无二次消费!",
"pteamprice": 3699
},
{
"pteamId": 72638,
"ptitle": "随摄影/服装不限数量/高品质拍摄260张/送全新婚纱。",
"pteamprice": 4299
},
{
"pteamId": 72716,
"ptitle": "随摄影/3组服装造型/内外景拍摄/完全透明消费!",
"pteamprice": 388
}
],
"liketeamlist": [
{
"lteamId": 65886,
"ltitle": "爱丽尔婚纱摄影/2本相册/6套服装造型/拍摄不限最低拍摄150张。",
"limage": "http://img.pztuan.com/upfile/team/2013/0712/201307120257551465.jpg",
"lteamprice": 518,
"lmarketprice": 3999
},
{
"lteamId": 57133,
"ltitle": "陶冶摄影/婚纱闺蜜/6组服装造型/拍摄不低于120张!",
"limage": "http://img.pztuan.com/upfile/team/2013/0628/201306281115249737.jpg",
"lteamprice": 580,
"lmarketprice": 3380
}
],
"feedbacks": {
"feedbacklist": [
{
"comment": "5分",
"createtime": "2014.07.08 13:38",
"score": 5,
"username": "l***2"
}
],
"totalcount": 1,
"totalscore": 5
}
},
"err": null,
"state": 1
}
实体类(里面的成员变量和接口的返回值名称一 一对应才能保证解析正确):
- import java.util.List;
- public class OtherDetail {
- private int state;
- private List<err> err;
- private OtherDetail2 data;
- public int getState() {
- return state;
- }
- public void setState(int state) {
- this.state = state;
- }
- public List<err> getErr() {
- return err;
- }
- public void setErr(List<err> err) {
- this.err = err;
- }
- public OtherDetail2 getData() {
- return data;
- }
- public void setData(OtherDetail2 data) {
- this.data = data;
- }
- public class OtherDetail2 {
- private List<partnerteamlist> partnerteamlist;
- private List<liketeamlist> liketeamlist;
- private List<feedbacks> feedbacks;
- public List<liketeamlist> getLiketeamlist() {
- return liketeamlist;
- }
- public void setLiketeamlist(List<liketeamlist> liketeamlist) {
- this.liketeamlist = liketeamlist;
- }
- public List<feedbacks> getFeedbacks() {
- return feedbacks;
- }
- public void setFeedbacks(List<feedbacks> feedbacks) {
- this.feedbacks = feedbacks;
- }
- public class partnerteamlist {
- private int pteamId;
- private String ptitle;
- private Double pteamprice;
- public int getPteamId() {
- return pteamId;
- }
- public void setPteamId(int pteamId) {
- this.pteamId = pteamId;
- }
- public String getPtitle() {
- return ptitle;
- }
- public void setPtitle(String ptitle) {
- this.ptitle = ptitle;
- }
- public Double getPteamprice() {
- return pteamprice;
- }
- public void setPteamprice(Double pteamprice) {
- this.pteamprice = pteamprice;
- }
- }
- public class liketeamlist {
- private int lteamId;
- private String ltitle;
- private String limage;
- private Double lteamprice;
- private Double lmarketprice;
- public int getLteamId() {
- return lteamId;
- }
- public void setLteamId(int lteamId) {
- this.lteamId = lteamId;
- }
- public String getLtitle() {
- return ltitle;
- }
- public void setLtitle(String ltitle) {
- this.ltitle = ltitle;
- }
- public String getLimage() {
- return limage;
- }
- public void setLimage(String limage) {
- this.limage = limage;
- }
- public Double getLteamprice() {
- return lteamprice;
- }
- public void setLteamprice(Double lteamprice) {
- this.lteamprice = lteamprice;
- }
- public Double getLmarketprice() {
- return lmarketprice;
- }
- public void setLmarketprice(Double lmarketprice) {
- this.lmarketprice = lmarketprice;
- }
- }
- public class feedbacks {
- private int totalcount;
- private Double totalscore;
- private List<feedbacklist> feedbacklist;
- public int getTotalcount() {
- return totalcount;
- }
- public void setTotalcount(int totalcount) {
- this.totalcount = totalcount;
- }
- public Double getTotalscore() {
- return totalscore;
- }
- public void setTotalscore(Double totalscore) {
- this.totalscore = totalscore;
- }
- public List<feedbacklist> getFeedbacklist() {
- return feedbacklist;
- }
- public void setFeedbacklist(List<feedbacklist> feedbacklist) {
- this.feedbacklist = feedbacklist;
- }
- public class feedbacklist {
- private String username;
- private String comment;
- private String createtime;
- private Double score;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getComment() {
- return comment;
- }
- public void setComment(String comment) {
- this.comment = comment;
- }
- public String getCreatetime() {
- return createtime;
- }
- public void setCreatetime(String createtime) {
- this.createtime = createtime;
- }
- public Double getScore() {
- return score;
- }
- public void setScore(Double score) {
- this.score = score;
- }
- }
- }
- public List<partnerteamlist> getPartnerteamlist() {
- return partnerteamlist;
- }
- public void setPartnerteamlist(List<partnerteamlist> partnerteamlist) {
- this.partnerteamlist = partnerteamlist;
- }
- }
- public class err {
- private int code;
- private String msg;
- public int getCode() {
- return code;
- }
- public void setCode(int code) {
- this.code = code;
- }
- public String getMsg() {
- return msg;
- }
- public void setMsg(String msg) {
- this.msg = msg;
- }
- }
- }
package com.pztuan.entity;
import java.util.List;
public class OtherDetail {
private int state;
private List<err> err;
private OtherDetail2 data;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public List<err> getErr() {
return err;
}
public void setErr(List<err> err) {
this.err = err;
}
public OtherDetail2 getData() {
return data;
}
public void setData(OtherDetail2 data) {
this.data = data;
}
public class OtherDetail2 {
private List<partnerteamlist> partnerteamlist;
private List<liketeamlist> liketeamlist;
private List<feedbacks> feedbacks;
public List<liketeamlist> getLiketeamlist() {
return liketeamlist;
}
public void setLiketeamlist(List<liketeamlist> liketeamlist) {
this.liketeamlist = liketeamlist;
}
public List<feedbacks> getFeedbacks() {
return feedbacks;
}
public void setFeedbacks(List<feedbacks> feedbacks) {
this.feedbacks = feedbacks;
}
public class partnerteamlist {
private int pteamId;
private String ptitle;
private Double pteamprice;
public int getPteamId() {
return pteamId;
}
public void setPteamId(int pteamId) {
this.pteamId = pteamId;
}
public String getPtitle() {
return ptitle;
}
public void setPtitle(String ptitle) {
this.ptitle = ptitle;
}
public Double getPteamprice() {
return pteamprice;
}
public void setPteamprice(Double pteamprice) {
this.pteamprice = pteamprice;
}
}
public class liketeamlist {
private int lteamId;
private String ltitle;
private String limage;
private Double lteamprice;
private Double lmarketprice;
public int getLteamId() {
return lteamId;
}
public void setLteamId(int lteamId) {
this.lteamId = lteamId;
}
public String getLtitle() {
return ltitle;
}
public void setLtitle(String ltitle) {
this.ltitle = ltitle;
}
public String getLimage() {
return limage;
}
public void setLimage(String limage) {
this.limage = limage;
}
public Double getLteamprice() {
return lteamprice;
}
public void setLteamprice(Double lteamprice) {
this.lteamprice = lteamprice;
}
public Double getLmarketprice() {
return lmarketprice;
}
public void setLmarketprice(Double lmarketprice) {
this.lmarketprice = lmarketprice;
}
}
public class feedbacks {
private int totalcount;
private Double totalscore;
private List<feedbacklist> feedbacklist;
public int getTotalcount() {
return totalcount;
}
public void setTotalcount(int totalcount) {
this.totalcount = totalcount;
}
public Double getTotalscore() {
return totalscore;
}
public void setTotalscore(Double totalscore) {
this.totalscore = totalscore;
}
public List<feedbacklist> getFeedbacklist() {
return feedbacklist;
}
public void setFeedbacklist(List<feedbacklist> feedbacklist) {
this.feedbacklist = feedbacklist;
}
public class feedbacklist {
private String username;
private String comment;
private String createtime;
private Double score;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getCreatetime() {
return createtime;
}
public void setCreatetime(String createtime) {
this.createtime = createtime;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
}
}
public List<partnerteamlist> getPartnerteamlist() {
return partnerteamlist;
}
public void setPartnerteamlist(List<partnerteamlist> partnerteamlist) {
this.partnerteamlist = partnerteamlist;
}
}
public class err {
private int code;
private String msg;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
}
注意上面内部类的运用。
解析:
- Gson gson = new Gson();
- OtherDetail d = gson.fromJson(jsonString,Detail.class);//取值的时候就从父类一层一层调子类成员(重要)
Gson gson = new Gson();
OtherDetail d = gson.fromJson(jsonString,Detail.class);//取值的时候就从父类一层一层调子类成员(重要)
若出现引用异常,请查看Java内部类设计原则。
参考网址:
http://blog.chinaunix.net/uid-23392298-id-3130177.html
http://www.tuicool.com/articles/6NVrmu
http://blog.csdn.net/rain_butterfly/article/details/38404293?utm_source=tuicool
http://blog.csdn.net/caijunjun1006/article/details/11762841
http://www.cnblogs.com/menlsh/archive/2013/05/19/3087810.html