Android用GSon处理Json数据

来源:互联网 发布:阿里云短信授权委托书 编辑:程序博客网 时间:2024/06/04 17:20

目前解析json有三种工具:org.json(Java常用的解析),fastjson(阿里巴巴工程师开发的),Gson(Google官网出的),解析速度最快的是Gson,下载地址:https://code.google.com/p/google-gson/


什么是JSON:


JSON即JavaScript Object Natation, 它是一种轻量级的数据交换格式, 与XML一样, 是广泛被采用的客户端和服务端交互的解决方案.


JSON对象: 


JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, key-value对之间使用逗号分隔. 如:{"name":"coolxing", "age"=24, "male":true, "address":{"street":"huiLongGuan", "city":"beijing", "country":"china"}}. JSON对象的key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况.


JSON数组: 


JSON数组(array)以"["开始, 以"]"结束, 数组中的每一个元素可以是string, number, false, true, null, Object对象甚至是array数组, 数组间的元素使用逗号分隔. 如["coolxing", 24, {"street":"huiLongGuan", "city":"beijing", "country":"china"}].


Gson的基本使用方法:

通过获取JsonReader对象解析JSON数据:

String jsonData = "[{\"username\":\"arthinking\",\"userId\":001},{\"username\":\"Jason\",\"userId\":002}]";try{JsonReader reader = new JsonReader(new StringReader(jsonData));reader.beginArray();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(Exception e){e.printStackTrace();}

通过把JSON数据映射成一个对象,使用Gson对象的fromJson()方法获取一个对象数组进行操作:

创建JSON数据对应的一个POJO对象User.java:

public class User {private String username ;private int userId ;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}}

使用Gson对象获取User对象数据进行相应的操作:

Type listType = new TypeToken<LinkedList<User>>(){}.getType();Gson gson = new Gson();LinkedList<User> users = gson.fromJson(jsonData, listType);for (Iterator iterator = users.iterator(); iterator.hasNext();) {User user = (User) iterator.next();System.out.println(user.getUsername());System.out.println(user.getUserId());}

如果要处理的JSON字符串只包含一个JSON对象,则可以直接使用fromJson获取一个User对象:

String jsonData = "{\"username\":\"arthinking\",\"userId\":001}";Gson gson = new Gson();User user = gson.fromJson(jsonData, User.class);System.out.println(user.getUsername());System.out.println(user.getUserId());
解析复杂实例:

数据格式:

[java] view plaincopy
  1. {  
  2.     "data": {  
  3.         "partnerteamlist": [  
  4.             {  
  5.                 "pteamId"72825,  
  6.                 "ptitle""随摄影/共6套服装/准爸准妈共拍/免费肚画/底片全送。",  
  7.                 "pteamprice"288  
  8.             },  
  9.             {  
  10.                 "pteamId"72598,  
  11.                 "ptitle""随摄影/拍摄200张/4本相册/品质拍摄/送全新婚纱。",  
  12.                 "pteamprice"2888  
  13.             },  
  14.             {  
  15.                 "pteamId"72613,  
  16.                 "ptitle""随摄影/送全新婚纱/多外景拍摄/服装不限数量/绝无二次消费!",  
  17.                 "pteamprice"3699  
  18.             },  
  19.             {  
  20.                 "pteamId"72638,  
  21.                 "ptitle""随摄影/服装不限数量/高品质拍摄260张/送全新婚纱。",  
  22.                 "pteamprice"4299  
  23.             },  
  24.             {  
  25.                 "pteamId"72716,  
  26.                 "ptitle""随摄影/3组服装造型/内外景拍摄/完全透明消费!",  
  27.                 "pteamprice"388  
  28.             }  
  29.         ],  
  30.         "liketeamlist": [  
  31.             {  
  32.                 "lteamId"65886,  
  33.                 "ltitle""爱丽尔婚纱摄影/2本相册/6套服装造型/拍摄不限最低拍摄150张。",  
  34.                 "limage""http://img.pztuan.com/upfile/team/2013/0712/201307120257551465.jpg",  
  35.                 "lteamprice"518,  
  36.                 "lmarketprice"3999  
  37.             },  
  38.             {  
  39.                 "lteamId"57133,  
  40.                 "ltitle""陶冶摄影/婚纱闺蜜/6组服装造型/拍摄不低于120张!",  
  41.                 "limage""http://img.pztuan.com/upfile/team/2013/0628/201306281115249737.jpg",  
  42.                 "lteamprice"580,  
  43.                 "lmarketprice"3380  
  44.             }  
  45.         ],  
  46.         "feedbacks": {  
  47.             "feedbacklist": [  
  48.                 {  
  49.                     "comment""5分",  
  50.                     "createtime""2014.07.08 13:38",  
  51.                     "score"5,  
  52.                     "username""l***2"  
  53.                 }  
  54.             ],  
  55.             "totalcount"1,  
  56.             "totalscore"5  
  57.         }  
  58.     },  
  59.     "err"null,  
  60.     "state"1  
  61. }  

实体类(里面的成员变量和接口的返回值名称一 一对应才能保证解析正确):

[java] view plaincopy
  1. package com.pztuan.entity;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class OtherDetail {  
  6.   
  7.     private int state;  
  8.     private List<err> err;  
  9.     private OtherDetail2 data;  
  10.   
  11.     public int getState() {  
  12.         return state;  
  13.     }  
  14.   
  15.     public void setState(int state) {  
  16.         this.state = state;  
  17.     }  
  18.   
  19.     public List<err> getErr() {  
  20.         return err;  
  21.     }  
  22.   
  23.     public void setErr(List<err> err) {  
  24.         this.err = err;  
  25.     }  
  26.   
  27.     public OtherDetail2 getData() {  
  28.         return data;  
  29.     }  
  30.   
  31.     public void setData(OtherDetail2 data) {  
  32.         this.data = data;  
  33.     }  
  34.   
  35.     public class OtherDetail2 {  
  36.         private List<partnerteamlist> partnerteamlist;  
  37.         private List<liketeamlist> liketeamlist;  
  38.         private List<feedbacks> feedbacks;  
  39.   
  40.         public List<liketeamlist> getLiketeamlist() {  
  41.             return liketeamlist;  
  42.         }  
  43.   
  44.         public void setLiketeamlist(List<liketeamlist> liketeamlist) {  
  45.             this.liketeamlist = liketeamlist;  
  46.         }  
  47.   
  48.         public List<feedbacks> getFeedbacks() {  
  49.             return feedbacks;  
  50.         }  
  51.   
  52.         public void setFeedbacks(List<feedbacks> feedbacks) {  
  53.             this.feedbacks = feedbacks;  
  54.         }  
  55.   
  56.         public class partnerteamlist {  
  57.             private int pteamId;  
  58.             private String ptitle;  
  59.             private Double pteamprice;  
  60.   
  61.             public int getPteamId() {  
  62.                 return pteamId;  
  63.             }  
  64.   
  65.             public void setPteamId(int pteamId) {  
  66.                 this.pteamId = pteamId;  
  67.             }  
  68.   
  69.             public String getPtitle() {  
  70.                 return ptitle;  
  71.             }  
  72.   
  73.             public void setPtitle(String ptitle) {  
  74.                 this.ptitle = ptitle;  
  75.             }  
  76.   
  77.             public Double getPteamprice() {  
  78.                 return pteamprice;  
  79.             }  
  80.   
  81.             public void setPteamprice(Double pteamprice) {  
  82.                 this.pteamprice = pteamprice;  
  83.             }  
  84.   
  85.         }  
  86.   
  87.         public class liketeamlist {  
  88.             private int lteamId;  
  89.             private String ltitle;  
  90.             private String limage;  
  91.             private Double lteamprice;  
  92.             private Double lmarketprice;  
  93.   
  94.             public int getLteamId() {  
  95.                 return lteamId;  
  96.             }  
  97.   
  98.             public void setLteamId(int lteamId) {  
  99.                 this.lteamId = lteamId;  
  100.             }  
  101.   
  102.             public String getLtitle() {  
  103.                 return ltitle;  
  104.             }  
  105.   
  106.             public void setLtitle(String ltitle) {  
  107.                 this.ltitle = ltitle;  
  108.             }  
  109.   
  110.             public String getLimage() {  
  111.                 return limage;  
  112.             }  
  113.   
  114.             public void setLimage(String limage) {  
  115.                 this.limage = limage;  
  116.             }  
  117.   
  118.             public Double getLteamprice() {  
  119.                 return lteamprice;  
  120.             }  
  121.   
  122.             public void setLteamprice(Double lteamprice) {  
  123.                 this.lteamprice = lteamprice;  
  124.             }  
  125.   
  126.             public Double getLmarketprice() {  
  127.                 return lmarketprice;  
  128.             }  
  129.   
  130.             public void setLmarketprice(Double lmarketprice) {  
  131.                 this.lmarketprice = lmarketprice;  
  132.             }  
  133.         }  
  134.   
  135.         public class feedbacks {  
  136.             private int totalcount;  
  137.             private Double totalscore;  
  138.             private List<feedbacklist> feedbacklist;  
  139.   
  140.             public int getTotalcount() {  
  141.                 return totalcount;  
  142.             }  
  143.   
  144.             public void setTotalcount(int totalcount) {  
  145.                 this.totalcount = totalcount;  
  146.             }  
  147.   
  148.             public Double getTotalscore() {  
  149.                 return totalscore;  
  150.             }  
  151.   
  152.             public void setTotalscore(Double totalscore) {  
  153.                 this.totalscore = totalscore;  
  154.             }  
  155.   
  156.             public List<feedbacklist> getFeedbacklist() {  
  157.                 return feedbacklist;  
  158.             }  
  159.   
  160.             public void setFeedbacklist(List<feedbacklist> feedbacklist) {  
  161.                 this.feedbacklist = feedbacklist;  
  162.             }  
  163.   
  164.             public class feedbacklist {  
  165.                 private String username;  
  166.                 private String comment;  
  167.                 private String createtime;  
  168.                 private Double score;  
  169.   
  170.                 public String getUsername() {  
  171.                     return username;  
  172.                 }  
  173.   
  174.                 public void setUsername(String username) {  
  175.                     this.username = username;  
  176.                 }  
  177.   
  178.                 public String getComment() {  
  179.                     return comment;  
  180.                 }  
  181.   
  182.                 public void setComment(String comment) {  
  183.                     this.comment = comment;  
  184.                 }  
  185.   
  186.                 public String getCreatetime() {  
  187.                     return createtime;  
  188.                 }  
  189.   
  190.                 public void setCreatetime(String createtime) {  
  191.                     this.createtime = createtime;  
  192.                 }  
  193.   
  194.                 public Double getScore() {  
  195.                     return score;  
  196.                 }  
  197.   
  198.                 public void setScore(Double score) {  
  199.                     this.score = score;  
  200.                 }  
  201.   
  202.             }  
  203.         }  
  204.   
  205.         public List<partnerteamlist> getPartnerteamlist() {  
  206.             return partnerteamlist;  
  207.         }  
  208.   
  209.         public void setPartnerteamlist(List<partnerteamlist> partnerteamlist) {  
  210.             this.partnerteamlist = partnerteamlist;  
  211.         }  
  212.     }  
  213.   
  214.     public class err {  
  215.         private int code;  
  216.         private String msg;  
  217.   
  218.         public int getCode() {  
  219.             return code;  
  220.         }  
  221.   
  222.         public void setCode(int code) {  
  223.             this.code = code;  
  224.         }  
  225.   
  226.         public String getMsg() {  
  227.             return msg;  
  228.         }  
  229.   
  230.         public void setMsg(String msg) {  
  231.             this.msg = msg;  
  232.         }  
  233.     }  
  234. }  

注意上面内部类的运用。

解析:

[java] view plaincopy
  1. Gson gson = new Gson();  
  2. OtherDetail d = gson.fromJson(jsonString,Detail.class);//取值的时候就从父类一层一层调子类成员(重要)  

若出现引用异常,请查看Java内部类设计原则。


参考:http://www.itzhai.com/android-to-parse-json-data-using-gson.html

           http://blog.csdn.net/caijunjun1006/article/details/11762841

在Android中可以使用Gson解析JSON数据

首先,从 code.google.com/p/google-gson/downloads/list下载GsonAPI:

google-gson-1.7.1-release.zip

把gson-1.7.jar copy到libs(项目根目录新建一个libs文件夹)中。

可以使用以下两种方法解析JSON数据:

通过获取JsonReader对象解析JSON数据:

String jsonData = "[{\"username\":\"arthinking\",\"userId\":001},{\"username\":\"Jason\",\"userId\":002}]";try{JsonReader reader = new JsonReader(new StringReader(jsonData));reader.beginArray();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(Exception e){e.printStackTrace();}

通过把JSON数据映射成一个对象,使用Gson对象的fromJson()方法获取一个对象数组进行操作:

创建JSON数据对应的一个POJO对象User.java:

public class User {private String username ;private int userId ;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}}

使用Gson对象获取User对象数据进行相应的操作:

Type listType = new TypeToken<LinkedList<User>>(){}.getType();Gson gson = new Gson();LinkedList<User> users = gson.fromJson(jsonData, listType);for (Iterator iterator = users.iterator(); iterator.hasNext();) {User user = (User) iterator.next();System.out.println(user.getUsername());System.out.println(user.getUserId());}

如果要处理的JSON字符串只包含一个JSON对象,则可以直接使用fromJson获取一个User对象:

String jsonData = "{\"username\":\"arthinking\",\"userId\":001}";Gson gson = new Gson();User user = gson.fromJson(jsonData, User.class);System.out.println(user.getUsername());System.out.println(user.getUserId());

什么是JSON:

JSON即JavaScript Object Natation, 它是一种轻量级的数据交换格式, 与XML一样, 是广泛被采用的客户端和服务端交互的解决方案.

JSON对象: 

JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, key-value对之间使用逗号分隔. 如:{"name":"coolxing", "age"=24, "male":true, "address":{"street":"huiLongGuan", "city":"beijing", "country":"china"}}. JSON对象的key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况.

JSON数组: 

JSON数组(array)以"["开始, 以"]"结束, 数组中的每一个元素可以是string, number, false, true, null, Object对象甚至是array数组, 数组间的元素使用逗号分隔. 如["coolxing", 24, {"street":"huiLongGuan", "city":"beijing", "country":"china"}].

JSON数据的解析:

解析JSON数据, 首先需要明确待解析的是JSON Object还是JSON array, 然后需要确定采用哪种解析技术. android平台上一般有2种解析技术可供选择:android内置的org.json包和google的开源gson库. 以下将分别采用这两种技术解析JSON对象和JSON数组.


1.  采用android内置的org.json包解析JSON对象. 假设待解析的JSON数据为json = "{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}", 其中\用于转义表达式中的双引号. 首先定义2个JavaBean:

[java] view plaincopy
  1. package text.com.bean;  
  2.   
  3. public class Address {  
  4.     private String street;  
  5.     private String city;  
  6.     private String country;  
  7.   
  8.     public Address() {  
  9.         super();  
  10.     }  
  11.   
  12.     public Address(String street, String city, String country) {  
  13.         super();  
  14.         this.street = street;  
  15.         this.city = city;  
  16.         this.country = country;  
  17.     }  
  18.   
  19.     public String getStreet() {  
  20.         return street;  
  21.     }  
  22.   
  23.     public void setStreet(String street) {  
  24.         this.street = street;  
  25.     }  
  26.   
  27.     public String getCity() {  
  28.         return city;  
  29.     }  
  30.   
  31.     public void setCity(String city) {  
  32.         this.city = city;  
  33.     }  
  34.   
  35.     public String getCountry() {  
  36.         return country;  
  37.     }  
  38.   
  39.     public void setCountry(String country) {  
  40.         this.country = country;  
  41.     }  
  42.   
  43.     @Override  
  44.     public String toString() {  
  45.         return "Address [street=" + street + ", city=" + city + ", country="  
  46.                 + country + "]";  
  47.     }  
  48.   
  49. }  

[java] view plaincopy
  1. package text.com.bean;  
  2.   
  3. public class Person {  
  4.     private String name;  
  5.     private int age;  
  6.     private boolean male;  
  7.     private Address address;  
  8.   
  9.     public Person() {  
  10.         super();  
  11.     }  
  12.   
  13.     public Person(String name, int age, boolean male, Address address) {  
  14.         super();  
  15.         this.name = name;  
  16.         this.age = age;  
  17.         this.male = male;  
  18.         this.address = address;  
  19.     }  
  20.   
  21.     public String getName() {  
  22.         return name;  
  23.     }  
  24.   
  25.     public void setName(String name) {  
  26.         this.name = name;  
  27.     }  
  28.   
  29.     public int getAge() {  
  30.         return age;  
  31.     }  
  32.   
  33.     public void setAge(int age) {  
  34.         this.age = age;  
  35.     }  
  36.   
  37.     public boolean isMale() {  
  38.         return male;  
  39.     }  
  40.   
  41.     public void setMale(boolean male) {  
  42.         this.male = male;  
  43.     }  
  44.   
  45.     public Address getAddress() {  
  46.         return address;  
  47.     }  
  48.   
  49.     public void setAddress(Address address) {  
  50.         this.address = address;  
  51.     }  
  52.   
  53.     @Override  
  54.     public String toString() {  
  55.         return "Person [name=" + name + ", age=" + age + ", male=" + male  
  56.                 + ", address=" + address + "]";  
  57.     }  
  58.   
  59. }  

首先使用方法一解析代码如下:
[java] view plaincopy
  1. JSONObject jsonObject = new JSONObject(json);  
  2. String name = jsonObject.getString("name");  
  3. int age = jsonObject.getInt("age");  
  4. boolean male = jsonObject.getBoolean("male");  
  5. JSONObject addressJSON = jsonObject.getJSONObject("address");  
  6. String street = addressJSON.getString("street");  
  7. String city = addressJSON.getString("city");  
  8. String country = addressJSON.getString("country");  
  9. Address address = new Address(street, city, country);  
  10. Person person = new Person(name, age, male, address);  
  11. 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包, 并将其添加到项目中. 具体的解析代码如下:

[java] view plaincopy
  1. Gson gson = new Gson();  
  2. Person person = gson.fromJson(json, Person.class);  
  3. 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\"}}]", 解析代码如下:

[java] view plaincopy
  1. List<Person> persons = new ArrayList<Person>();  
  2. JSONArray jsonArray = new JSONArray(json);  
  3. for(int i = 0; i < jsonArray.length(); i++) {  
  4.     JSONObject jsonObject = jsonArray.getJSONObject(i);  
  5.     String name = jsonObject.getString("name");  
  6.     int age = jsonObject.getInt("age");  
  7.     boolean male = jsonObject.getBoolean("male");  
  8.     JSONObject addressJSON = jsonObject.getJSONObject("address");  
  9.     String street = addressJSON.getString("street");  
  10.     String city = addressJSON.getString("city");  
  11.     String country = addressJSON.getString("country");  
  12.     Address address = new Address(street, city, country);  
  13.     Person person = new Person(name, age, male, address);  
  14.     persons.add(person);  
  15. }  
  16. System.out.println(persons);  
LogCat的输出为[Person [name=coolxing, age=24, male=true, address=Address [street=huiLongGuan, city=beijing, country=china]], Person [name=min, age=20, male=false, address=Address [street=heiShiJiao, city=daLian, country=china]]], 说明已经正确解析了JSON数组.

4. 采用gson库解析JSON数组. 待解析的JSON数据同上, 具体代码为:
[java] view plaincopy
  1. Gson gson = new Gson();  
  2. Type listType = new TypeToken<List<Person>>(){}.getType();  
  3. List<Person> persons = gson.fromJson(json, listType);  
LogCat的输出为[Person [name=coolxing, age=24, male=true, address=Address [street=huiLongGuan, city=beijing, country=china]], Person [name=min, age=20, male=false, address=Address [street=heiShiJiao, city=daLian, country=china]]], 说明已经正确解析了JSON数组.
new TypeToken<List<Person>>(){}.getType(); 这句代码表示创建一个TypeToken的匿名子类对象, 并调用对象的getType()方法.

org.json包和gson库还有很多其他有用的API, 需要的时候可查看文档. 比如有的时候需要通过java对象或java集合和数组生成json数据上传给服务器, 当然你可以自我构造json字符串, 但会很麻烦. 这个时候就可以使用其中的有关API, 方便的完成这项工作.



测试用例:

[java] view plaincopy
  1. package text.com;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.InputStreamReader;  
  7. import java.lang.reflect.Type;  
  8. import java.util.List;  
  9.   
  10. import text.com.bean.Address;  
  11. import text.com.bean.Person;  
  12.   
  13. import com.google.gson.Gson;  
  14. import com.google.gson.reflect.TypeToken;  
  15.   
  16. public class JsonTest {  
  17.     String jsonString = "";  
  18.   
  19.     public static void main(String[] args) {  
  20.         // Person p1 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",  
  21.         // "30号"));  
  22.         // Person p2 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",  
  23.         // "30号"));  
  24.         // Person p3 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",  
  25.         // "30号"));  
  26.         // List<Person> list = new ArrayList<Person>();  
  27.         // list.add(p1);  
  28.         // list.add(p2);  
  29.         // list.add(p3);  
  30.         // Gson gson = new Gson();  
  31.         // Type typeOfT = new TypeToken<List<Person>>(){}.getType();  
  32.         // String json = gson.toJson(list, typeOfT);  
  33.         // System.out.println("json:"+json);  
  34.   
  35.         // String str = readTxtFile("D:\\cjjworkspace\\Test\\json.txt");  
  36.         // System.out.println("文件内容:" + str);  
  37.          Gson gson = new Gson();  
  38.         // Type typeOfT = new TypeToken<List<Person>>(){}.getType();  
  39.         // List<Person> personList = gson.fromJson(str, typeOfT);  
  40.   
  41.         Person p1 = new Person("zhangsan"12truenew Address("北京""海淀区""30号"));  
  42.         Type typeOfT = new TypeToken<Person>(){}.getType();  
  43.         String str = gson.toJson(p1, typeOfT);  
  44.         System.out.println(str);  
  45.     }  
  46.   
  47.     public static String readTxtFile(String filePath) {  
  48.         String encoding = "utf-8";  
  49.         StringBuilder sb = new StringBuilder();  
  50.         try {  
  51.             File file = new File(filePath);  
  52.             if (file.isFile() && file.exists()) { // 判断文件是否存在  
  53.                 InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式  
  54.                 BufferedReader bufferedReader = new BufferedReader(read);  
  55.                 String str = "";  
  56.                 while ((str = bufferedReader.readLine()) != null) {  
  57.                     sb.append(str);  
  58.                 }  
  59.                 read.close();  
  60.                 return sb.toString();  
  61.             } else {  
  62.                 System.out.println("找不到指定的文件");  
  63.                 return null;  
  64.             }  
  65.         } catch (Exception e) {  
  66.             System.out.println("读取文件内容出错");  
  67.             e.printStackTrace();  
  68.         }  
  69.         return sb.toString();  
  70.     }  
  71. }  



附带:gson-2.2.4.jar

           gson-2.2.4-javadoc.jar

           gson-2.2.4-sources.jar


  1. Android用GSon处理Json数据  
  2. http://www.javaask.com/mobile/android/2011/0420/6948.html  
  3. package com.demo;  
  4.   
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.io.UnsupportedEncodingException;  
  8.   
  9. import org.apache.http.HttpEntity;  
  10. import org.apache.http.HttpResponse;  
  11. import org.apache.http.client.methods.HttpGet;  
  12. import org.apache.http.impl.client.DefaultHttpClient;  
  13. import org.apache.http.params.BasicHttpParams;  
  14. import org.apache.http.protocol.HTTP;  
  15.   
  16. import android.util.Log;  
  17.   
  18. public class WebDataGetApi {  
  19.   
  20.     private static final String TAG = "WebDataGetAPI";  
  21.     private static final String USER_AGENT = "Mozilla/4.5";  
  22.   
  23.     protected String getRequest(String url) throws Exception {  
  24.         return getRequest(url, new DefaultHttpClient(new BasicHttpParams()));  
  25.     }  
  26.   
  27.     protected String getRequest(String url, DefaultHttpClient client)  
  28.             throws Exception {  
  29.         String result = null;  
  30.         int statusCode = 0;  
  31.         HttpGet getMethod = new HttpGet(url);  
  32.         Log.d(TAG, "do the getRequest,url=" + url + "");  
  33.         try {  
  34.             getMethod.setHeader("User-Agent", USER_AGENT);  
  35.             // HttpParams params = new HttpParams();  
  36.   
  37.             // 添加用户密码验证信息  
  38.             // client.getCredentialsProvider().setCredentials(  
  39.             // new AuthScope(null, -1),  
  40.             // new UsernamePasswordCredentials(mUsername, mPassword));  
  41.   
  42.             HttpResponse httpResponse = client.execute(getMethod);  
  43.             // statusCode == 200 正常  
  44.             statusCode = httpResponse.getStatusLine().getStatusCode();  
  45.             Log.d(TAG, "statuscode = " + statusCode);  
  46.             // 处理返回的httpResponse信息  
  47.             result = retrieveInputStream(httpResponse.getEntity());  
  48.         } catch (Exception e) {  
  49.             Log.e(TAG, e.getMessage());  
  50.             throw new Exception(e);  
  51.         } finally {  
  52.             getMethod.abort();  
  53.         }  
  54.         return result;  
  55.     }  
  56.   
  57.     /** 
  58.      * 处理httpResponse信息,返回String 
  59.      *  
  60.      * @param httpEntity 
  61.      * @return String 
  62.      */  
  63.     protected String retrieveInputStream(HttpEntity httpEntity) {  
  64.         int length = (int) httpEntity.getContentLength();  
  65.         if (length < 0)  
  66.             length = 10000;  
  67.         StringBuffer stringBuffer = new StringBuffer(length);  
  68.         try {  
  69.             InputStreamReader inputStreamReader = new InputStreamReader(  
  70.                     httpEntity.getContent(), HTTP.UTF_8);  
  71.             char buffer[] = new char[length];  
  72.             int count;  
  73.             while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {  
  74.                 stringBuffer.append(buffer, 0, count);  
  75.             }  
  76.         } catch (UnsupportedEncodingException e) {  
  77.             Log.e(TAG, e.getMessage());  
  78.         } catch (IllegalStateException e) {  
  79.             Log.e(TAG, e.getMessage());  
  80.         } catch (IOException e) {  
  81.             Log.e(TAG, e.getMessage());  
  82.         }  
  83.         return stringBuffer.toString();  
  84.     }  
  85. }  
  86.   
  87. 二. 建立JsonDataGetApi.java  
  88.   
  89. package com.demo;  
  90.   
  91. import org.json.JSONArray;  
  92. import org.json.JSONException;  
  93. import org.json.JSONObject;  
  94.   
  95. public class JsonDataGetApi extends WebDataGetApi {  
  96.     private static final String BASE_URL = "http://10.0.2.2:82/AccountService/";  
  97.     private static final String EXTENSION = "Json/";;  
  98.   
  99.     public JSONObject getObject(String sbj) throws JSONException, Exception {  
  100.         return new JSONObject(getRequest(BASE_URL + EXTENSION + sbj));  
  101.     }  
  102.   
  103.     public JSONArray getArray(String sbj) throws JSONException, Exception {  
  104.         return new JSONArray(getRequest(BASE_URL + EXTENSION + sbj));  
  105.     }  
  106. }  
  107.   
  108. 三. 建立Android端Account模型Account.java  
  109.   
  110. package com.demo;  
  111.   
  112. import java.util.Date;  
  113.   
  114. public class Account {  
  115.   
  116.     public String Name;  
  117.   
  118.     public int Age;  
  119.   
  120.     public String Address;  
  121.   
  122.     public Date Birthday;  
  123. }  
  124.   
  125. 四. 在我们的主Activity中调用刚才的方法, 在这一步中我们需要引入Google的gson 库gson-1.6.jar至我们的工程(下载地址)  
  126.   
  127. package com.demo;  
  128.   
  129. import java.util.Date;  
  130.   
  131. import org.json.JSONArray;  
  132. import org.json.JSONObject;  
  133.   
  134. import com.google.gson.Gson;  
  135. import com.google.gson.GsonBuilder;  
  136.   
  137. import android.app.Activity;  
  138. import android.os.Bundle;  
  139. import android.util.Log;  
  140. import android.widget.TextView;  
  141. import android.widget.Toast;  
  142.   
  143. public class WebData extends Activity {  
  144.     /** Called when the activity is first created. */  
  145.     @Override  
  146.     public void onCreate(Bundle savedInstanceState) {  
  147.         super.onCreate(savedInstanceState);  
  148.         setContentView(R.layout.main);  
  149.         getJsonData();  
  150.     }  
  151.   
  152.     public void getJsonData() {  
  153.         JsonDataGetApi api = new JsonDataGetApi();  
  154.         JSONArray jArr;  
  155.         JSONObject jobj;  
  156.         try {  
  157.             //调用GetAccountData方法  
  158.             jArr = api.getArray("GetAccountData");  
  159.             //从返回的Account Array中取出第一个数据  
  160.             jobj = jArr.getJSONObject(0);  
  161.               
  162.           GsonBuilder gsonb = new GsonBuilder();  
  163.             //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.  
  164.             //DateDeserializer ds = new DateDeserializer();  
  165.             //给GsonBuilder方法单独指定Date类型的反序列化方法  
  166.               //gsonb.registerTypeAdapter(Date.class, ds);  
  167.               
  168.             Gson gson = gsonb.create();  
  169.   
  170.             Account account = gson.fromJson(jobj.toString(), Account.class);  
  171.   
  172.             Log.d("LOG_CAT", jobj.toString());  
  173.             ((TextView) findViewById(R.id.Name)).setText(account.Name);  
  174.             ((TextView) findViewById(R.id.Age)).setText(account.Age);  
  175.             ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday  
  176.                     .toGMTString());  
  177.             ((TextView) findViewById(R.id.Address)).setText(account.Address);  
  178.   
  179.         } catch (Exception e) {  
  180.             Toast.makeText(getApplicationContext(), e.getMessage(),  
  181.                     Toast.LENGTH_LONG).show();  
  182.             e.printStackTrace();  
  183.             TextView movie_Address = (TextView) findViewById(R.id.Address);  
  184.             movie_Address.setText(e.getMessage());  
  185.         }  
  186.     }  
  187. }  
  188.   
  189.    
  190.   
  191. 五.我们开始构建UI  
  192.   
  193. 打开layout下的main.xml  
  194.   
  195. <?xml version="1.0" encoding="utf-8"?>  
  196. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  197.     android:orientation="vertical" android:layout_width="fill_parent"  
  198.     android:layout_height="fill_parent">  
  199.     <TextView android:id="@+id/Name" android:layout_width="fill_parent"  
  200.         android:layout_height="wrap_content" />  
  201.     <TextView android:id="@+id/Age" android:layout_width="fill_parent"  
  202.         android:layout_height="wrap_content" />  
  203.     <TextView android:id="@+id/Birthday" android:layout_width="fill_parent"  
  204.         android:layout_height="wrap_content" />  
  205.     <TextView android:id="@+id/Address" android:layout_width="fill_parent"  
  206.         android:layout_height="wrap_content" />  
  207. </LinearLayout>  
  208.   
  209. 在配置好RunConfiguration之后,我们开始运行程序,  查看Log发现有以下错误,  
  210.   
  211. image  
  212.   
  213. 意思是说访问被禁止,也就是未授权访问,  其意思并不是我们的服务未授权, 因为Andriod具有很好的很好很好的安全机制, 我们要访问网络必须要经过授权才可以;  
  214.   
  215. 我们打开res目录下AndroidManifest.xml, 注意字体加粗放大的那句, 就是给我们的程序加入Internet的访问授权.  
  216.   
  217. <?xml version="1.0" encoding="utf-8"?>  
  218. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  219.       package="com.demo"  
  220.       android:versionCode="1"  
  221.       android:versionName="1.0">  
  222.         
  223.       <uses-permission android:name="android.permission.INTERNET"></uses-permission>  
  224.   
  225.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  226.         <activity android:name=".WebData"  
  227.                   android:label="@string/app_name">  
  228.             <intent-filter>  
  229.                 <action android:name="android.intent.action.MAIN" />  
  230.                 <category android:name="android.intent.category.LAUNCHER" />  
  231.             </intent-filter>  
  232.         </activity>  
  233.   
  234.     </application>  
  235. </manifest>  
  236.   
  237.    
  238.   
  239. 再次运行程序, 会发现显示如下:  
  240.   
  241. image  
  242.   
  243. image  
  244.   
  245. 从上图中的statuscode = 200来看,说明我们的请求已经成功, 问题出现在Json Parse(Json数据转换/反序列化/格式化)的过程中, 我们现在把从服务器传过来的数据拿出来看看, 在浏览器输入我们的服务地址: http://localhost:82/AccountService/Json/GetAccountData   
  246.   
  247. [  
  248.  {  
  249.      "Address""YouYi East Road",  
  250.      "Age"56,  
  251.      "Birthday""/Date(1298605481453+0800)/",  
  252.      "Name""Bill Gates"  
  253.  },  
  254.  {  
  255.      "Address""YouYi West Road",  
  256.      "Age"57,  
  257.      "Birthday""/Date(1298605481453+0800)/",  
  258.      "Name""Steve Paul Jobs"  
  259.  },  
  260.  {  
  261.      "Address""YouYi North Road",  
  262.      "Age"65,  
  263.      "Birthday""/Date(1298605481453+0800)/",  
  264.      "Name""John D. Rockefeller"  
  265.  }  
  266. ]  
  267.   
  268.    
  269.   
  270. 我们发现其中的Birthday的结果并非我们想象中yyyy-mm-dd HH:mm:ss类型, 究其原因可以查看MSDN文章《JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 简介》  
  271.   
  272. 现在我们给我们的GsonBuilder指定Date的序列化方法, 先增加一个Date反序列化的类DateDeserializer.java  
  273.   
  274. package com.demo;  
  275.   
  276. import java.lang.reflect.Type;  
  277. import java.util.Date;  
  278. import java.util.regex.Matcher;  
  279. import java.util.regex.Pattern;  
  280.   
  281. import com.google.gson.JsonDeserializationContext;  
  282. import com.google.gson.JsonDeserializer;  
  283. import com.google.gson.JsonElement;  
  284. import com.google.gson.JsonParseException;  
  285.   
  286. public class DateDeserializer implements JsonDeserializer<Date> {  
  287.     public Date deserialize(JsonElement json, Type typeOfT,  
  288.             JsonDeserializationContext context) throws JsonParseException {  
  289.         String JSONDateToMilliseconds = "\\/(Date\\((.*?)(\\+.*)?\\))\\/";  
  290.         Pattern pattern = Pattern.compile(JSONDateToMilliseconds);  
  291.         Matcher matcher = pattern.matcher(json.getAsJsonPrimitive()  
  292.                 .getAsString());  
  293.         String result = matcher.replaceAll("$2");  
  294.         return new Date(new Long(result));  
  295.     }  
  296. }  
  297.   
  298. 其次修改Activity类中的GetDate方法如下, 注意其中加粗的部分.  
  299.   
  300.     public void getJsonData() {  
  301.         JsonDataGetApi api = new JsonDataGetApi();  
  302.         JSONArray jArr;  
  303.         JSONObject jobj;  
  304.         try {  
  305.             //调用GetAccountData方法  
  306.             jArr = api.getArray("GetAccountData");  
  307.             //从返回的Account Array中取出第一个数据  
  308.             jobj = jArr.getJSONObject(0);  
  309.               
  310.             GsonBuilder gsonb = new GsonBuilder();  
  311.             //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.  
  312.             DateDeserializer ds = new DateDeserializer();  
  313.             //给GsonBuilder方法单独指定Date类型的反序列化方法  
  314.               gsonb.registerTypeAdapter(Date.class, ds);  
  315.               
  316.             Gson gson = gsonb.create();  
  317.   
  318.             Account account = gson.fromJson(jobj.toString(), Account.class);  
  319.   
  320.             Log.d("LOG_CAT", jobj.toString());  
  321.             ((TextView) findViewById(R.id.Name)).setText(account.Name);  
  322.             ((TextView) findViewById(R.id.Age)).setText(String.valueOf(account.Age));  
  323.             ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday  
  324.                     .toGMTString());  
  325.             ((TextView) findViewById(R.id.Address)).setText(account.Address);  
  326.   
  327.         } catch (Exception e) {  
  328.             Toast.makeText(getApplicationContext(), e.getMessage(),  
  329.                     Toast.LENGTH_LONG).show();  
  330.             e.printStackTrace();  
  331.         }  
  332.     }  
  333. }  
  334.   
  335.    
  336.   
  337. 我们现在再运行程序 :  
  338.   
  339. image  
  340.   
  341. 执行成功.  
Android 强大的JSON助手 GSON
//转换器
        GsonBuilder builder = new GsonBuilder(); 
        // 不转换没有 @Expose 注解的字段 
        builder.excludeFieldsWithoutExposeAnnotation();
        Gson gson = builder.create(); 
        
        //1、对象转string
        Student stu = new Student();
        stu.setStudentId(333);
        stu.setStudentName("qqq");
        String stuStr = gson.toJson(stu);
        System.out.println(stuStr); //{"studentName":"qqq","studentId":333}
        
        
        //2、string转对象
        Student user2 = gson.fromJson(stuStr, Student.class); 
        System.out.println(user2); 
        String stuTemp = "{\"studentName\":\"qqq2\",\"studentId\":3335}";
        Student user4 = gson.fromJson(stuTemp, Student.class); 
        System.out.println(user4); 

        //3、对象List转string
        List<Student> testBeanList = new ArrayList<Student>(); 
        Student testBean = new Student(); 
        testBean.setStudentId(555);
        testBean.setStudentName("552");
        testBeanList.add(testBean); 
        
        //Gson gsonList = new Gson(); 
        Type type = new TypeToken<List<Student>>(){}.getType();  //指定集合对象属性
        String beanListToJson = gson.toJson(testBeanList, type); 
        System.out.println(beanListToJson); //[{"studentName":"552","studentId":555}] 

        //集合string转对象list
        List<Student> testBeanListFromJson = gson.fromJson(beanListToJson, type); 
        System.out.println(testBeanListFromJson); //[555:552]

        //4、集合如果不指定类型 默认为String
        List<String> testList = new ArrayList<String>(); 
        testList.add("first"); 
        testList.add("second"); 
        String listToJson = gson.toJson(testList); 
        System.out.println(listToJson); //["first","second"] 
        
        //5、集合字符串转回来需要指定类型
        List<String> testList2 = (List<String>) gson.fromJson(listToJson, 
          new TypeToken<List<String>>() { 
          }.getType()); 
        System.out.println(testList2); 

        //6、 将HashMap字符串转换为 JSON 
        Map<String, String> testMap = new HashMap<String, String>(); 
        testMap.put("id", "id.first"); 
        testMap.put("name", "name.second"); 
        String mapToJson = gson.toJson(testMap); 
        System.out.println(mapToJson); //{"id":"id.first","name":"name.second"}
        //7、stringMap转对象
        Map<String, String> userMap2 = (Map<String, String>) gson.fromJson(mapToJson, 
                new TypeToken<Map<String, String>>() { 
            }.getType()); 
        System.out.println(userMap2); //{id=id.first, name=name.second} 

        //8、对象含有普通对象、集合、map情况
        Student user1 = new Student(); 
        user1.setStudentId(1001); 
        user1.setStudentName("张三"); 
        
        Student user3 = new Student(); 
        user3.setStudentId(1002); 
        user3.setStudentName("李四"); 
        
        Map<String, Student> userMap = new HashMap<String, Student>(); 
        userMap.put("user1", user1); 
        userMap.put("user3", user3); 
        
        List<Student> userList = new ArrayList<Student>(); 
        userList.add(user1); 
        userList.add(user3); 
        
        Teacher groupBean = new Teacher(); 
        groupBean.setStudent(user1);
        groupBean.setStus(userList);
        groupBean.setMap((HashMap)userMap);
        //groupBean.setUserList(userList); 
        Gson gsonGroup = new Gson(); 

        String sGroupBean = gsonGroup.toJson(groupBean, new TypeToken<Teacher>() { 
            }.getType()); 
        System.out.println(sGroupBean); 
        /*{"stus":[{"studentName":"张三","studentId":1001},{"studentName":"李四","studentId":1002}],"student":{"studentName":"张三","studentId":1001},"map":{"user3":{"studentName":"李四","studentId":1002},"user1":{"studentName":"张三","studentId":1001}},"id":0,"age":0}*/

 

        //9、复杂对象string转对象
        Teacher groupBean2 = (Teacher) gson.fromJson(sGroupBean, 
              new TypeToken<Teacher>() { 
              }.getType()); 
        System.out.println(groupBean2); 

 

 

package com.andtools;

import com.google.gson.annotations.Expose;

public class Student {
    @Expose
    private String studentName;
    @Expose
    private int studentId;
    public Student(){}
    public Student(int studentId,String studentName){
        this.setStudentId(studentId);
        this.setStudentName(studentName);
    }
    public String toString(){
        return this.getStudentId() + ":" + this.getStudentName();
    }
    public String getStudentName() {
        return studentName;
    }
    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }
    public int getStudentId() {
        return studentId;
    }
    public void setStudentId(int studentId) {
        this.studentId = studentId;
    }
    
}

 

package com.andtools;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gson.annotations.Expose;

public class Teacher {
    @Expose
    private int id;
    @Expose
    private String name;
    @Expose
    private int age;
    @Expose
    private Student student;
    @Expose
    private List stus;
    @Expose
    private HashMap map;
    public String toString(){
        return this.getId()+":"+this.getName()+":"+this.getAge() +":"+ this.getStudent().toString() + ":" + this.getStus() + ":" + this.getMap();
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    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 Student getStudent() {
        return student;
    }
    public void setStudent(Student student) {
        this.student = student;
    }
    public List getStus() {
        return stus;
    }
    public void setStus(List stus) {
        this.stus = stus;
    }
    public HashMap getMap() {
        return map;
    }
    public void setMap(HashMap map) {
        this.map = map;
    }
    
}

 

一. 建立我们包装好的Http请求类文件 WebDataGetApi.java

  1. package com.demo;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStreamReader;  
  5. import java.io.UnsupportedEncodingException;  
  6.   
  7. import org.apache.http.HttpEntity;  
  8. import org.apache.http.HttpResponse;  
  9. import org.apache.http.client.methods.HttpGet;  
  10. import org.apache.http.impl.client.DefaultHttpClient;  
  11. import org.apache.http.params.BasicHttpParams;  
  12. import org.apache.http.protocol.HTTP;  
  13.   
  14. import android.util.Log;  
  15.   
  16. public class WebDataGetApi {  
  17.   
  18.     private static final String TAG = "WebDataGetAPI";  
  19.     private static final String USER_AGENT = "Mozilla/4.5";  
  20.   
  21.     protected String getRequest(String url) throws Exception {  
  22.         return getRequest(url, new DefaultHttpClient(new BasicHttpParams()));  
  23.     }  
  24.   
  25.     protected String getRequest(String url, DefaultHttpClient client)  
  26.             throws Exception {  
  27.         String result = null;  
  28.         int statusCode = 0;  
  29.         HttpGet getMethod = new HttpGet(url);  
  30.         Log.d(TAG, "do the getRequest,url=" + url + "");  
  31.         try {  
  32.             getMethod.setHeader("User-Agent", USER_AGENT);  
  33.             // HttpParams params = new HttpParams();  
  34.   
  35.             // 添加用户密码验证信息  
  36.             // client.getCredentialsProvider().setCredentials(  
  37.             // new AuthScope(null, -1),  
  38.             // new UsernamePasswordCredentials(mUsername, mPassword));  
  39.   
  40.             HttpResponse httpResponse = client.execute(getMethod);  
  41.             // statusCode == 200 正常  
  42.             statusCode = httpResponse.getStatusLine().getStatusCode();  
  43.             Log.d(TAG, "statuscode = " + statusCode);  
  44.             // 处理返回的httpResponse信息  
  45.             result = retrieveInputStream(httpResponse.getEntity());  
  46.         } catch (Exception e) {  
  47.             Log.e(TAG, e.getMessage());  
  48.             throw new Exception(e);  
  49.         } finally {  
  50.             getMethod.abort();  
  51.         }  
  52.         return result;  
  53.     }  
  54.   
  55.     /** 
  56.      * 处理httpResponse信息,返回String 
  57.      *  
  58.      * @param httpEntity 
  59.      * @return String 
  60.      */  
  61.     protected String retrieveInputStream(HttpEntity httpEntity) {  
  62.         int length = (int) httpEntity.getContentLength();  
  63.         if (length < 0)  
  64.             length = 10000;  
  65.         StringBuffer stringBuffer = new StringBuffer(length);  
  66.         try {  
  67.             InputStreamReader inputStreamReader = new InputStreamReader(  
  68.                     httpEntity.getContent(), HTTP.UTF_8);  
  69.             char buffer[] = new char[length];  
  70.             int count;  
  71.             while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {  
  72.                 stringBuffer.append(buffer, 0, count);  
  73.             }  
  74.         } catch (UnsupportedEncodingException e) {  
  75.             Log.e(TAG, e.getMessage());  
  76.         } catch (IllegalStateException e) {  
  77.             Log.e(TAG, e.getMessage());  
  78.         } catch (IOException e) {  
  79.             Log.e(TAG, e.getMessage());  
  80.         }  
  81.         return stringBuffer.toString();  
  82.     }  
  83. }  
二. 建立JsonDataGetApi.java
  1. package com.demo;  
  2.   
  3. import org.json.JSONArray;  
  4. import org.json.JSONException;  
  5. import org.json.JSONObject;  
  6.   
  7. public class JsonDataGetApi extends WebDataGetApi {  
  8.     private static final String BASE_URL = "http://10.0.2.2:82/AccountService/";  
  9.     private static final String EXTENSION = "Json/";;  
  10.   
  11.     public JSONObject getObject(String sbj) throws JSONException, Exception {  
  12.         return new JSONObject(getRequest(BASE_URL + EXTENSION + sbj));  
  13.     }  
  14.   
  15.     public JSONArray getArray(String sbj) throws JSONException, Exception {  
  16.         return new JSONArray(getRequest(BASE_URL + EXTENSION + sbj));  
  17.     }  
  18. }  

三. 建立Android端Account模型Account.java

  1. import java.util.Date;  
  2.   
  3. public class Account {  
  4.   
  5.     public String Name;  
  6.   
  7.     public int Age;  
  8.   
  9.     public String Address;  
  10.   
  11.     public Date Birthday;  
  12. }  
四. 在我们的主Activity中调用刚才的方法, 在这一步中我们需要引入Google的gson 库gson-1.6.jar至我们的工程(下载地址)
  1. package com.demo;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import org.json.JSONArray;  
  6. import org.json.JSONObject;  
  7.   
  8. import com.google.gson.Gson;  
  9. import com.google.gson.GsonBuilder;  
  10.   
  11. import android.app.Activity;  
  12. import android.os.Bundle;  
  13. import android.util.Log;  
  14. import android.widget.TextView;  
  15. import android.widget.Toast;  
  16.   
  17. public class WebData extends Activity {  
  18.     /** Called when the activity is first created. */  
  19.     @Override  
  20.     public void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.main);  
  23.         getJsonData();  
  24.     }  
  25.   
  26.     public void getJsonData() {  
  27.         JsonDataGetApi api = new JsonDataGetApi();  
  28.         JSONArray jArr;  
  29.         JSONObject jobj;  
  30.         try {  
  31.             //调用GetAccountData方法  
  32.             jArr = api.getArray("GetAccountData");  
  33.             //从返回的Account Array中取出第一个数据  
  34.             jobj = jArr.getJSONObject(0);  
  35.               
  36.           GsonBuilder gsonb = new GsonBuilder();  
  37.             //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.  
  38.             //DateDeserializer ds = new DateDeserializer();  
  39.             //给GsonBuilder方法单独指定Date类型的反序列化方法  
  40.               //gsonb.registerTypeAdapter(Date.class, ds);  
  41.               
  42.             Gson gson = gsonb.create();  
  43.   
  44.             Account account = gson.fromJson(jobj.toString(), Account.class);  
  45.   
  46.             Log.d("LOG_CAT", jobj.toString());  
  47.             ((TextView) findViewById(R.id.Name)).setText(account.Name);  
  48.             ((TextView) findViewById(R.id.Age)).setText(account.Age);  
  49.             ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday  
  50.                     .toGMTString());  
  51.             ((TextView) findViewById(R.id.Address)).setText(account.Address);  
  52.   
  53.         } catch (Exception e) {  
  54.             Toast.makeText(getApplicationContext(), e.getMessage(),  
  55.                     Toast.LENGTH_LONG).show();  
  56.             e.printStackTrace();  
  57.             TextView movie_Address = (TextView) findViewById(R.id.Address);  
  58.             movie_Address.setText(e.getMessage());  
  59.         }  
  60.     }  
  61. }  
五.我们开始构建UI

打开layout下的main.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical" android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.     <TextView android:id="@+id/Name" android:layout_width="fill_parent"  
  6.         android:layout_height="wrap_content" />  
  7.     <TextView android:id="@+id/Age" android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content" />  
  9.     <TextView android:id="@+id/Birthday" android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content" />  
  11.     <TextView android:id="@+id/Address" android:layout_width="fill_parent"  
  12.         android:layout_height="wrap_content" />  
  13. </LinearLayout>  
在配置好RunConfiguration之后,我们开始运行程序,  查看Log发现有以下错误,

意思是说访问被禁止,也就是未授权访问,  其意思并不是我们的服务未授权, 因为Andriod具有很好的很好很好的安全机制, 我们要访问网络必须要经过授权才可以;

我们打开res目录下AndroidManifest.xml, 注意字体加粗放大的那句, 就是给我们的程序加入Internet的访问授权.

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.demo"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.         
  7.       <uses-permission android:name="android.permission.INTERNET"></uses-permission>  
  8.   
  9.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  10.         <activity android:name=".WebData"  
  11.                   android:label="@string/app_name">  
  12.             <intent-filter>  
  13.                 <action android:name="android.intent.action.MAIN" />  
  14.                 <category android:name="android.intent.category.LAUNCHER" />  
  15.             </intent-filter>  
  16.         </activity>  
  17.   
  18.     </application>  
  19. </manifest>  
再次运行程序, 会发现显示如下:

 

 

从上图中的statuscode = 200来看,说明我们的请求已经成功, 问题出现在Json Parse(Json数据转换/反序列化/格式化)的过程中, 我们现在把从服务器传过来的数据拿出来看看, 在浏览器输入我们的服务地址: http://localhost:82/AccountService/Json/GetAccountData 

[ {     "Address": "YouYi East Road",     "Age": 56,     "Birthday": "/Date(1298605481453+0800)/",     "Name": "Bill Gates" }, {     "Address": "YouYi West Road",     "Age": 57,     "Birthday": "/Date(1298605481453+0800)/",     "Name": "Steve Paul Jobs" }, {     "Address": "YouYi North Road",     "Age": 65,     "Birthday": "/Date(1298605481453+0800)/",     "Name": "John D. Rockefeller" }]

我们发现其中的Birthday的结果并非我们想象中yyyy-mm-dd HH:mm:ss类型, 究其原因可以查看MSDN文章《JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 简介》

现在我们给我们的GsonBuilder指定Date的序列化方法, 先增加一个Date反序列化的类DateDeserializer.java

  1. package com.demo;  
  2.   
  3. import java.lang.reflect.Type;  
  4. import java.util.Date;  
  5. import java.util.regex.Matcher;  
  6. import java.util.regex.Pattern;  
  7.   
  8. import com.google.gson.JsonDeserializationContext;  
  9. import com.google.gson.JsonDeserializer;  
  10. import com.google.gson.JsonElement;  
  11. import com.google.gson.JsonParseException;  
  12.   
  13. public class DateDeserializer implements JsonDeserializer<Date> {  
  14.     public Date deserialize(JsonElement json, Type typeOfT,  
  15.             JsonDeserializationContext context) throws JsonParseException {  
  16.         String JSONDateToMilliseconds = "\\/(Date\\((.*?)(\\+.*)?\\))\\/";  
  17.         Pattern pattern = Pattern.compile(JSONDateToMilliseconds);  
  18.         Matcher matcher = pattern.matcher(json.getAsJsonPrimitive()  
  19.                 .getAsString());  
  20.         String result = matcher.replaceAll("$2");  
  21.         return new Date(new Long(result));  
  22.     }  
  23. }  
其次修改Activity类中的GetDate方法如下, 注意其中加粗的部分.
  1.     public void getJsonData() {  
  2.         JsonDataGetApi api = new JsonDataGetApi();  
  3.         JSONArray jArr;  
  4.         JSONObject jobj;  
  5.         try {  
  6.             //调用GetAccountData方法  
  7.             jArr = api.getArray("GetAccountData");  
  8.             //从返回的Account Array中取出第一个数据  
  9.             jobj = jArr.getJSONObject(0);  
  10.               
  11.             GsonBuilder gsonb = new GsonBuilder();  
  12.             //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.  
  13.             DateDeserializer ds = new DateDeserializer();  
  14.             //给GsonBuilder方法单独指定Date类型的反序列化方法  
  15.               gsonb.registerTypeAdapter(Date.class, ds);  
  16.               
  17.             Gson gson = gsonb.create();  
  18.   
  19.             Account account = gson.fromJson(jobj.toString(), Account.class);  
  20.   
  21.             Log.d("LOG_CAT", jobj.toString());  
  22.             ((TextView) findViewById(R.id.Name)).setText(account.Name);  
  23.             ((TextView) findViewById(R.id.Age)).setText(String.valueOf(account.Age));  
  24.             ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday  
  25.                     .toGMTString());  
  26.             ((TextView) findViewById(R.id.Address)).setText(account.Address);  
  27.   
  28.         } catch (Exception e) {  
  29.             Toast.makeText(getApplicationContext(), e.getMessage(),  
  30.                     Toast.LENGTH_LONG).show();  
  31.             e.printStackTrace();  
  32.         }  
  33.     }  
  34. }  
  35. <span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>  
我们现在再运行程序 :

 

执行成功.

示例下载

Java代码  收藏代码
  1. //转换器  
  2.         GsonBuilder builder = new GsonBuilder();   
  3.         // 不转换没有 @Expose 注解的字段   
  4.         builder.excludeFieldsWithoutExposeAnnotation();  
  5.         Gson gson = builder.create();   
  6.           
  7.         //1、对象转string  
  8.         Student stu = new Student();  
  9.         stu.setStudentId(333);  
  10.         stu.setStudentName("qqq");  
  11.         String stuStr = gson.toJson(stu);  
  12.         System.out.println(stuStr); //{"studentName":"qqq","studentId":333}  
  13.           
  14.           
  15.         //2、string转对象  
  16.         Student user2 = gson.fromJson(stuStr, Student.class);   
  17.         System.out.println(user2);   
  18.         String stuTemp = "{\"studentName\":\"qqq2\",\"studentId\":3335}";  
  19.         Student user4 = gson.fromJson(stuTemp, Student.class);   
  20.         System.out.println(user4);   
  21.   
  22.         //3、对象List转string  
  23.         List<Student> testBeanList = new ArrayList<Student>();   
  24.         Student testBean = new Student();   
  25.         testBean.setStudentId(555);  
  26.         testBean.setStudentName("552");  
  27.         testBeanList.add(testBean);   
  28.           
  29.         //Gson gsonList = new Gson();   
  30.         Type type = new TypeToken<List<Student>>(){}.getType();  //指定集合对象属性  
  31.         String beanListToJson = gson.toJson(testBeanList, type);   
  32.         System.out.println(beanListToJson); //[{"studentName":"552","studentId":555}]   
  33.   
  34.         //集合string转对象list  
  35.         List<Student> testBeanListFromJson = gson.fromJson(beanListToJson, type);   
  36.         System.out.println(testBeanListFromJson); //[555:552]  
  37.   
  38.         //4、集合如果不指定类型 默认为String  
  39.         List<String> testList = new ArrayList<String>();   
  40.         testList.add("first");   
  41.         testList.add("second");   
  42.         String listToJson = gson.toJson(testList);   
  43.         System.out.println(listToJson); //["first","second"]   
  44.           
  45.         //5、集合字符串转回来需要指定类型  
  46.         List<String> testList2 = (List<String>) gson.fromJson(listToJson,   
  47.           new TypeToken<List<String>>() {   
  48.           }.getType());   
  49.         System.out.println(testList2);   
  50.   
  51.         //6、 将HashMap字符串转换为 JSON   
  52.         Map<String, String> testMap = new HashMap<String, String>();   
  53.         testMap.put("id""id.first");   
  54.         testMap.put("name""name.second");   
  55.         String mapToJson = gson.toJson(testMap);   
  56.         System.out.println(mapToJson); //{"id":"id.first","name":"name.second"}  
  57.         //7、stringMap转对象  
  58.         Map<String, String> userMap2 = (Map<String, String>) gson.fromJson(mapToJson,   
  59.                 new TypeToken<Map<String, String>>() {   
  60.             }.getType());   
  61.         System.out.println(userMap2); //{id=id.first, name=name.second}   
  62.   
  63.         //8、对象含有普通对象、集合、map情况  
  64.         Student user1 = new Student();   
  65.         user1.setStudentId(1001);   
  66.         user1.setStudentName("张三");   
  67.           
  68.         Student user3 = new Student();   
  69.         user3.setStudentId(1002);   
  70.         user3.setStudentName("李四");   
  71.           
  72.         Map<String, Student> userMap = new HashMap<String, Student>();   
  73.         userMap.put("user1", user1);   
  74.         userMap.put("user3", user3);   
  75.           
  76.         List<Student> userList = new ArrayList<Student>();   
  77.         userList.add(user1);   
  78.         userList.add(user3);   
  79.           
  80.         Teacher groupBean = new Teacher();   
  81.         groupBean.setStudent(user1);  
  82.         groupBean.setStus(userList);  
  83.         groupBean.setMap((HashMap)userMap);  
  84.         //groupBean.setUserList(userList);   
  85.         Gson gsonGroup = new Gson();   
  86.   
  87.         String sGroupBean = gsonGroup.toJson(groupBean, new TypeToken<Teacher>() {   
  88.             }.getType());   
  89.         System.out.println(sGroupBean);   
  90.         /*{"stus":[{"studentName":"张三","studentId":1001},{"studentName":"李四","studentId":1002}],"student":{"studentName":"张三","studentId":1001},"map":{"user3":{"studentName":"李四","studentId":1002},"user1":{"studentName":"张三","studentId":1001}},"id":0,"age":0}*/  
Java代码  收藏代码
  1. //9、复杂对象string转对象  
  2. Teacher groupBean2 = (Teacher) gson.fromJson(sGroupBean,   
  3.    new TypeToken<Teacher>() {   
  4.    }.getType());   
  5. System.out.println(groupBean2);   

 

Java代码  收藏代码
  1. package com.andtools;  
  2.   
  3. import com.google.gson.annotations.Expose;  
  4.   
  5. public class Student {  
  6.     @Expose  
  7.     private String studentName;  
  8.     @Expose  
  9.     private int studentId;  
  10.     public Student(){}  
  11.     public Student(int studentId,String studentName){  
  12.         this.setStudentId(studentId);  
  13.         this.setStudentName(studentName);  
  14.     }  
  15.     public String toString(){  
  16.         return this.getStudentId() + ":" + this.getStudentName();  
  17.     }  
  18.     public String getStudentName() {  
  19.         return studentName;  
  20.     }  
  21.     public void setStudentName(String studentName) {  
  22.         this.studentName = studentName;  
  23.     }  
  24.     public int getStudentId() {  
  25.         return studentId;  
  26.     }  
  27.     public void setStudentId(int studentId) {  
  28.         this.studentId = studentId;  
  29.     }  
  30.       
  31. }  

 

Java代码  收藏代码
  1. package com.andtools;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. import com.google.gson.annotations.Expose;  
  8.   
  9. public class Teacher {  
  10.     @Expose  
  11.     private int id;  
  12.     @Expose  
  13.     private String name;  
  14.     @Expose  
  15.     private int age;  
  16.     @Expose  
  17.     private Student student;  
  18.     @Expose  
  19.     private List stus;  
  20.     @Expose  
  21.     private HashMap map;  
  22.     public String toString(){  
  23.         return this.getId()+":"+this.getName()+":"+this.getAge() +":"this.getStudent().toString() + ":" + this.getStus() + ":" + this.getMap();  
  24.     }  
  25.     public int getId() {  
  26.         return id;  
  27.     }  
  28.     public void setId(int id) {  
  29.         this.id = id;  
  30.     }  
  31.     public String getName() {  
  32.         return name;  
  33.     }  
  34.     public void setName(String name) {  
  35.         this.name = name;  
  36.     }  
  37.     public int getAge() {  
  38.         return age;  
  39.     }  
  40.     public void setAge(int age) {  
  41.         this.age = age;  
  42.     }  
  43.     public Student getStudent() {  
  44.         return student;  
  45.     }  
  46.     public void setStudent(Student student) {  
  47.         this.student = student;  
  48.     }  
  49.     public List getStus() {  
  50.         return stus;  
  51.     }  
  52.     public void setStus(List stus) {  
  53.         this.stus = stus;  
  54.     }  
  55.     public HashMap getMap() {  
  56.         return map;  
  57.     }  
  58.     public void setMap(HashMap map) {  
  59.         this.map = map;  
  60.     }  
  61.       
  62. }  

 

附件为网上找的文档。

  • gson使用.rar (7.7 KB)
  • 下载次数: 809

经过比较,gson和其他现有java json类库最大的不同时gson需要序列化得实体类不需要使用annotation来标识需要序列化得字段,同时gson又可以通过使用annotation来灵活配置需要序列化的字段。

下面是一个简单的例子:

复制代码
public class Person {

private String name;
private int age;

/**
*
@return the name
*/
public String getName() {
return name;
}

/**
*
@param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
*
@return the age
*/
public int getAge() {
return age;
}

/**
*
@param age the age to set
*/
public void setAge(int age) {
this.age = age;
}

@Override
public String toString()
{
return name + ":" +age;
}
}
复制代码

实体很简单,两个字段,当然实体中的字段也可以是List或者Set类型的。

复制代码
Gson gson = new Gson();
List
<Person> persons = new ArrayList<Person>();
for (int i = 0; i < 10; i++) {
Person p
= new Person();
p.setName(
"name" + i);
p.setAge(i
* 5);
persons.add(p);
}
String str
= gson.toJson(persons);
复制代码

上面的代码重点是Gson对象,它提供了toJason()方法将对象转换成Json字符串,上面代码的str对象值为:

[{"name":"name0","age":0},{"name":"name1","age":5},{"name":"name2","age":10},{"name":"name3","age":15},{"name":"name4","age":20},{"name":"name5","age":25},{"name":"name6","age":30},{"name":"name7","age":35},{"name":"name8","age":40},{"name":"name9","age":45}]

很标准的json数据,很简单吧,呵呵。

下面来看看gson的反序列化,Gson提供了fromJson()方法来实现从Json相关对象到java实体的方法。

在日常应用中,我们一般都会碰到两种情况,转成单一实体对象和转换成对象列表或者其他结构。

先来看第一种:

比如json字符串为:[{"name":"name0","age":0}]

代码:

Person person = gson.fromJson(str, Person.class);

提供两个参数,分别是json字符串以及需要转换对象的类型。

第二种,转换成列表类型:

代码:

List<Person> ps = gson.fromJson(str, new TypeToken<List<Person>>(){}.getType());
for(int i = 0; i < ps.size() ; i++)
{
Person p
= ps.get(i);
System.out.println(p.toString());
}

可以看到上面的代码使用了TypeToken,它是gson提供的数据类型转换器,可以支持各种数据集合类型转换。

Gson的基本使用就是这么多,至于annotation方面可以参考gson的官方文档,希望能对初学java和gson的同学有所帮助。

在Java/Android开发中,我们经常需要从服务器请求信息,返回的数据格式一般都是XML(extensible markup language)或者JSON(JavaScript Object Notation)格式。在Android开发中,轻量级的数据交互首选JSON,但XML依然大量使用在数据量比较大或者特殊字符比较多等数据交换情形,而且XML在可读性方面还是优于JSON格式的。这里简要地记述一下对xml数据解析的三种使用方法,方便日后温习。
  XML文档解析可以采用的方法:DOM(Document Object Module)、SAX(Simple API for XML)和PULL方式。DOM和SAX解析方式都已经集成在Java里面了,Sun公司提供了Java API for XML Parsing(JAXP)接口来使用DOM和SAX,我们可以使用任何与JAXP兼容的XML解析器。JAXP接口包含了三个包:
  (1)org.w3c.dom W3C推荐的用于XML标准规划文档对象模型的接口。 
  (2)org.xml.sax  用于对XML进行语法分析的事件驱动的XML简单API(SAX)
  (3)javax.xml.parsers解析器工厂工具,可以获得并配置特殊的特殊语法分析器。
  而Pull解析方式则需要引入第三方工具包(目前我找到的最新版kxml2-2.3.0.jar,好像还没api文档可供下载http://kxml.objectweb.org)。
  DOM方式把一切都当作一个节点,文档节点、元素节点、文本节点、注释节点etc。它把整个XML文档当作一个Document对象,解析时需要把整个xml文档加载到内存中,解析完成后根据XML文档的节点结构生成文件树。可在程序中随意存取文件树,没有次数限制。显然DOM方式并不适合解析大的XML文档,太耗内存。
  sax方式具有解析器和事件处理器,解析器负责读取XML文档和向事件处理器发送事件(充当事件源),事件处理器负责对发送的事件响应和进行XML文档处理。SAX方式采用流处理方式,边解析边触发相应的事件。不需要把整个xml文档加载进内存,边解析边丢弃,解析速度快,占用内存少,很适合移动开发。SAX是层次型的解析,只能依次对xml文档的数据流处理一遍,不支持对数据的任意存取操作(自己用变量保存解析结果另说)。使用sax方式不需要事先知道xml文档的每一个节点名称,主要的工作是写事件处理类。
  pull方式跟sax方式很像,也是事件驱动型的。pull方式的结构非常简单,最重要的两个方法就是next()和nextToken(),最常用的几个属性【parser是XmlPullParser解析器对象】:
   parser.START DOCUMENT
  parser.START_TAG
  parser.TEXT
  parser.END_TAG
  parser.END_DOCUMENT
  
  下面贴一下主要的示例代码片段:
首先在tomcat服务器端放一个xml文档person.xml,内容如下:

 1 2 3 4 5 6 7 8 9101112131415
<?xml version="1.0" encoding="utf-8"?><persons>    <person id="23">        <name>叫兽</name>        <age>21</age>    </person>    <person id="20">        <name>李四</name>        <age>25</age>    </person>    <person id="10">        <name>淫贼</name>        <age>20</age>    </person></persons>

在客户端程序里面需要写一个类来操作得到的xml节点信息,这里统一都用Person.java类:

 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627
public class Person {    private int id;    private String name;    private int age;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    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;    }    @Override    public String toString() {        return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";    }}

统一使用HttpUtils.java类从tomcat服务器上面得到xml文档的数据流

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829
public class HttpUtils {    /**     * 根据路径获取服务器端的xml文件数据流     * @param path xml所在的服务器文件路径     * @return InputStream xml文件的数据流     */    public static InputStream getXML(String path) {        InputStream inputStream = null;        try {            URL url = new URL(path);            if (url != null) {                HttpURLConnection connection = (HttpURLConnection) url                        .openConnection();                connection.setConnectTimeout(3000);                connection.setDoInput(true);                connection.setRequestMethod("GET");                int code = connection.getResponseCode();                if (code == 200) {//连接成功                    inputStream = connection.getInputStream();                    return inputStream;                }            }        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();        }        return null;    }}

DOM方式解析xml文档的主要操作:

 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829
public List<Person> getPersons(InputStream inputStream) throws Exception{        List<Person> list=new ArrayList<Person>();        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建一个document解析的工厂        DocumentBuilder builder = factory.newDocumentBuilder();//dom解析器,此时整个xml文件已经保存在内存中        Document document = builder.parse(inputStream);//解析xml文件流获得文档对象        Element element = document.getDocumentElement();// 获得文档元素节点//      element.getFirstChild()//逐个节点往下读        NodeList personNodeList = element.getElementsByTagName("person");        int len=personNodeList.getLength();        for (int i = 0; i < len; i++) {            Element personElement = (Element) personNodeList.item(i);            Person person = new Person();            person.setId(Integer.parseInt(personElement.getAttribute("id")));            NodeList childNodes = personElement.getChildNodes();            for (int j = 0; j < childNodes.getLength(); j++) {                if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {//判断节点类型为元素节点                    if ("name".equals(childNodes.item(j).getNodeName())) {//name子节点                        person.setName(childNodes.item(j).getFirstChild()                                .getNodeValue());                    } else if ("age".equals(childNodes.item(j).getNodeName())) {//age子节点                        person.setAge(Integer.parseInt(childNodes.item(j)                                .getFirstChild().getNodeValue()));                    }                }            }            list.add(person);        }        return list;    }

DOM方式的测试类Test.java

 1 2 3 4 5 6 7 8 9101112131415161718192021
public class Test {    /**     * @param args     */    public static void main(String[] args) {        // TODO Auto-generated method stub        String path="http://localhost:8080/myhttp/person.xml";        InputStream inputStream=HttpUtils.getXML(path);        DomParseService service=new DomParseService();        try {            List<Person> list=service.getPersons(inputStream);            for(Person person:list){                System.out.println(person.toString());            }        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

SAX方式主要操作集中在事件处理器上(代码有点多,省略),简要说说这个事件处理类MyHandler.java的实现。这个类需要继承DefaultHandler类,同时在类的构造函数中传入当前解析的节点名称。主要是重写以下几个方法来处理事件:
1.public void startDocument() throws SAXException {//接收文档开始时触发}
2.public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {//接收第一个元素时触发事件
3.public void characters(char[] ch, int start, int length)throws SAXException {//接收元素中字符数据时出发,这里面处理xml文档信息}
4.public void endElement(String uri, String localName, String qName)throws SAXException {//遇到文档结束标记时触发}
SAX方式解析的主要业务逻辑:

 1 2 3 4 5 6 7 8 9101112131415
public static List<HashMap<String, String>> readXML(            InputStream inputStream, String nodeName) {        try {            SAXParserFactory spFactory=SAXParserFactory.newInstance();//实例化SAX解析器工厂对象            SAXParser parser=spFactory.newSAXParser();//创建解析器            MyHandler handler=new MyHandler(nodeName);//实例化事件处理器            parser.parse(inputStream, handler);//绑定xml流和事件处理器            inputStream.close();            return handler.getList();        } catch (Exception e) {            // TODO: handle exception            e.printStackTrace();        }        return null;    }

PUll方式解析的主要类PullXMLTools.java(测试代码参考DOM方式):

 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445
public class PullXMLTools {    /**     * @param inputStream 服务器取得的流     * @param encode 编码格式     * @return     * @throws Exception      */    public static List<Person> parseXML(InputStream inputStream,String encode) throws Exception{        List<Person> list=null;        Person person=null;        //创建一个解析器工厂        XmlPullParserFactory factory=XmlPullParserFactory.newInstance();        //获得xml解析类的引用        XmlPullParser parser =factory.newPullParser();        parser.setInput(inputStream, encode);        //获得事件的类型        int eventType=parser.getEventType();        while(eventType!=XmlPullParser.END_DOCUMENT){            switch (eventType) {            case XmlPullParser.START_DOCUMENT:                list=new ArrayList<Person>();//新建一个list存储对象                break;            case XmlPullParser.START_TAG:                if("person".equals(parser.getName())){                    person=new Person();                    person.setId(Integer.parseInt(parser.getAttributeValue(0)));//取出属性值                }else if("name".equals(parser.getName())){                    person.setName(parser.nextText());                }else if("age".equals(parser.getName())){                    person.setAge(Integer.parseInt(parser.nextText()));//                }                break;            case XmlPullParser.END_TAG:                if("person".equals(parser.getName())){                    list.add(person);                    person=null;                }                break;            }            eventType=parser.next();        }        return list;    }}
============================================================================================

============================================================================================

跟xml解析一样,json也有很多可供选择的解析包,其中比较常用的有jackson、gson、org.json等(PS:据说阿里的fastjson也不错,可惜那个文档真心蛋疼)。Android一开始就自带了org.json的解析包,在Android 3.0开始又集成了google自己的gson解析包,即新增的android.util.JsonReader和android.util.JsonWriter类。由于目前Android 2.3等低版本仍然占有比较大的比重,从兼容性的角度考虑,目前开发中一般还是选择org.json或者导入gson等解析包

json的基本格式

从json的全称JavaScript Object Notation就可以猜测它跟JavaScript的“亲戚”关系,其实这个轻量级的数据交换格式是基于JavaScript的一个子集,说白了就是js的对象和数组。json采用了独立于语言的文本格式,有两种基本数据结构:对象和数组(两者各种嵌套形成较复杂的json数据)。
Json Array放在中括号[]里面,如[a,c,d...],就跟我们熟悉的数组没本质区别。数组中的元素可以是string, number, false, true, null, Object对象甚至是array数组。下面是官网给的图解:
array.jpg
Json Object放在大括号{}里面,表示成键值对{key1:value1, key2:value2, key3:value3,....}。其中(在面向对象的语言里)key为对象的属性,value为对应的属性值。key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况。下面是官网给的图解:
object.jpg
解析json数据首先需要知道解析的是json数组还是json对象!下面将简单介绍一下gson和org.json包的基本使用。解析json内容前建议先根据json的内容建立相应的存储或者表示结构,本文例子里面都将使用到一个Person实体类:

 1 2 3 4 5 6 7 8 91011121314151617
public class Person {    private String name;    private  int age;    public Person() {        super();    }    public Person(String name, int age) {        super();        this.name = name;        this.age = age;    }    @Override    public String toString() {        return "Person [name="   name   ", age="   age   "]";    } //注:这里省略相应的setter和getter方法}

在本文中还用到 一些YY出来的json数据内容:

12345678
private String jsonArray = "[{"name":"Jack","age":20}, {"name":"mike","age":23},"             " {"name":"mary","age":22}]";//待解析的json数组,数组元素是嵌套的json对象    private String jsonObject="{"name":"Object","age":30}";//待解析的json对象    private List<Person> persons=new ArrayList<Person>();//假定ArrayList里面的数据需要转换成json格式以供传输//同时在onCreate()里面把persons初始化为:    persons.add(new Person("你妹",11 ));    persons.add(new Person("你弟",23 ));    persons.add(new Person("二货",33 ));

使用gson解析包

要想使用gson解析包必须首先下载并导入解析包,目前我在官网上看到的最新版本是gson-2.2.4.jar。gson里面通常可以采用两种方式来解析一个json格式数据:第一种方式就是采用JsonReader 逐字符解析json,利用beginArray()和endArray()方法来标志整个数组的开始和结束,解析json对象时采用类似的beginObject()和endObject()方法来标记开头和结尾。下面的第一种解析json数组的方法基本是**跟Android 3.0以后自带的android.util.JsonReader里面的解析方式类似**:

 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243
    /**     * 解析json数组的第一种方式     * @param jsonArray     * @return     */    public List<Person> parseJson(String jsonArray) {        // TODO Auto-generated method stub        try {            //首先需要一个JsonReader对象,传入一个Reader参数            JsonReader reader=new JsonReader(new StringReader(jsonArray));            reader.beginArray();//根据jsonArray可知道第一步要解析数组 即遇到了数组的"["            while(reader.hasNext()){                arrList.add(readObject(reader));//读取数组元素            }            reader.endArray();//解析数组结束 遇到了数组的"]"        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return arrList;    }    /**     * 解析数组里面的json对象组成的元素     * @param reader     * @return     * @throws Exception     */    private Person readObject(JsonReader reader) throws Exception {        // TODO Auto-generated method stub        String name=null;        int    age=0;        reader.beginObject();//开始解析对象,遇到了数组元素的'{'        while(reader.hasNext()){//开始解析对象里面的键值对            String key=reader.nextName();//得到key            if(key.equals("name")){                name=reader.nextString();//取得value值            }else if(key.equals("age")){                age=reader.nextInt();            }        }        reader.endObject();//结束对象的解析 遇到了'}'        return new Person(name, age);    }

此外,在gson里面还有另外一种集成好的更方便的解析方式,下面这段代码可以达到跟方法一样的解析结果,代码显得更简洁

 1 2 3 4 5 6 7 8 91011
    /**     * 解析json数组的第二种方式     * @param jsonArray     * @return     */    public List<Person> parseJson2(String jsonArray){        TypeToken<List<Person>> list = new TypeToken<List<Person>>() {};        Gson gson=new Gson();        arrList=gson.fromJson(jsonArray, list.getType());        return arrList;    }

如果待解析的json数据是一个简单的json对象,那么可以采用类似方法1中的readObject()的步骤去解析,也可以采用类似方法2中的方式:

 1 2 3 4 5 6 7 8 910
    /**     * 解析一个简单的json对象,效果跟法1中的readObject()方法类似     * @param jsonObject     * @return     */    public List<Person> parseJsonObject(String jsonObject){        Gson gson=new Gson();        arrList.add(gson.fromJson(jsonObject, Person.class));        return arrList;    }

两种方式解析String jsonArray的结果(输出格式按Person类重写的toString()方法):
jsonarray.jpg

String jsonObject的解析结果(输出格式按Person类重写的toString()方法):
jsonObject.jpg

上面这些两种方法都是关于解析json数据的,比如说服务器给客户端传来的json格式数据就可以采用相似的方式去解析。下面简单介绍一下如何把上面YY出来的List persons里面的内容转变成json数组,以便客户端上传给服务器:

1234
    public String toJsonString(List<Person> persons) {        Gson gson=new Gson();        return gson.toJson(persons);    }

运行结果为:
tojson.jpg

==========================================================================================================================

使用org.json来解析

Android 里面的org.json包里面有四个类JSONArray、JSONObject、JSONStringer、JSONTokener和一个异常JSONException。这几个类的主要作用为:

  • JSONArray:表示的就是上文提到的json数组
  • JSONObject:表示的就是上文提到的json对象
  • JSONStringer:这个类主要用来生成符合json格式的文本,可以减少由于格式错误导致的程序异常。
  • JSONTokener:负责把一个json格式文本转换成相应的对象,这个类既可以把json文本转换成对象(如JSONObject,JSONArray,String,Boolean,Integer,Long,Double or NULL),还可以读取其中的一个个字符(char)。正如官方文档上说的,大多数用户只是使用到这个类的构造方法和nextValue()方法。

JSONArray和JSONObject类

提供的方法主要有:各种构造方法、get××()、opt××(),put(××××)。其中put()方法用来添加或者替换数值,get××和opt××方法在功能上非常类似,都可以根据key或者索引取得json里面的数据项,但它们有个非常重要的区别:

  • get××()方法没找到相应key的情况下,会抛出JSONException异常
  • opt××()方法没找到相应key的情况下,会返回一个null值,并不会抛出JSONException异常

下面通过一个简单的例子来看看JSONObject类的使用(JSONArray类似,略):

 1 2 3 4 5 6 7 8 9101112131415
        //JSONObject JSONArray的使用示例        String json="{'name':'阿波','age':30}";        Map<String,Object> map=new HashMap<String, Object>();        map.put("name", "Map");        map.put("age", 11);        try {//          JSONObject object=new JSONObject(json);//利用String来构造            JSONObject object=new JSONObject(map);//利用map来构造,还有其他构造方法不再罗列了            //两个方法的主要区别上面已经简单介绍了            tv_json.setText("取得的名字:"+ object.getString("name") +"n取得的年龄:" +object.optInt("age"));        } catch (JSONException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }

解析的结果为:
3.jpg2.jpg

JSONStringer类

主要的方法有:array()、endArray()、object()、endObject()、key()、value()和toString()。显然这几个方法都是成对使用的,具体点就是:

  • object()表明开始一个JSON对象,即添加"{",endObject()表结束,即添加"}";
  • array()表明开始一个JSON数组,即添加一个"[" ,endArray()表结束,即添加"]" ;
  • key()表示添加一个key,value()表示添加一个value,构成key:value键值对。

简单的使用示例:

 1 2 3 4 5 6 7 8 91011121314151617
try {            //l利用JSONStringer生成一串json数据,缩进略怪,易懂就行            JSONStringer stringer=new JSONStringer().object()                    .key("name").value("阿海")                    .key("age").value("20")                    .key("address").value("北京海淀")                    .key("girlfriend")                        .array()                            .value("阿猫").value("阿狗").value("阿猪")                        .endArray()                    .key("phone").value("13411111111")                    .endObject();            tv_json.setText("把stringer转成字符串输出:"+stringer.toString());//输出显示        } catch (JSONException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }

得到的结果(如下图)为一个json对象里面嵌套一个简单的json数组,更复杂的json格式文本按这方式建立即可:
1.jpg

JSONTokener类

Android集成的org.json包里面的JSONTokener只有一个构造方法JSONTokener(String in) ,类里面提供了不少方法,但一般常使用的只有nextValue()方法,其他主要方法的详细解释见代码注释。
简单的使用示例:

 1 2 3 4 5 6 7 8 910111213141516171819202122
        //JSONTokener的使用示例        String json="{'name':'阿波','age':30,'兴趣':['读书','睡觉','吃饭']}";        try {            JSONTokener tokener=new JSONTokener(json);//org.json包里面的JSONTokener只有唯一构造函数//          JSONObject object=new JSONObject(tokener);//这个也是JSONObject的构造方法之一,将一次性把这个JSONObject读取完//          tv_json.setText(object.toString());             String a,b,c,d;            a=tokener.nextString('g');//当前位置到第一个 g 中间的内容(不包括当前字符 g ),即    {'name':'阿波','a            b=String.valueOf(tokener.next());//从当前所在位置(age的'g'处)继续往下读一个字符(若遇到中文也是一个字符) ,即 e            c=String.valueOf(tokener.next(10));//age后面数10个字符,即 ':30,'兴趣':            //读取下一个JSONObject,JSONArray,String,Boolean,Integer,Long,Double or NULL            JSONArray array=(JSONArray) tokener.nextValue();//读取下一个JSONArray,即 ['读书','睡觉','吃饭']            d=String.valueOf(tokener.nextClean());//读取下一个非空白或者评论内容的字符,这里即 }            tv_json.setText("tokener.nextString('g')=" a                         +"ntokener.next()=" b                         +"ntokener.next(10)=" c                         +"ntokener.nextValue())=" array.toString()                         +"ntokener.nextClean()=" d);        } catch (JSONException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }

运行结果:
4.jpg

以上示例代码的tv_json.setText()是上文提到的TextView对象,但tv_json.setText()输出里面的字符串连接符(加号+),有些浏览器没显示出来,忽略它。


0 0
原创粉丝点击