Android原生json类org.json.JSONObject初步使用

 

Android原生json类只提供了很简单的几个方法,也没有内置bean的操作,但是由于其实android原生,支持比较好。比如服务器端常用的json-lib这个库,在android上面就无法使用,原因是json-lib的依赖包commons-collection无法支持;

首先,最常用的方法:从json字符串中根据键名获取相对应的值:

1、new 一个JSONObject对象,构造里放入json字符串

2、用jsonOBject对象的getString("属性名“),getInt("属性名“),或者get("属性名")方法得到对应的值

 

 
  1. JSONObject jsonObject;

  2. try {

  3. jsonObject = new JSONObject("{name:'jack',age:12}");

  4. String name = jsonObject.getString("name");

  5. int age = jsonObject.getInt("age");

  6. System.out.println(name+age);

  7. } catch (JSONException e1) {

  8. // TODO Auto-generated catch block

  9. e1.printStackTrace();

  10. }


如果我们想要把json字符串解析成一个java对应类的对象,就不能指望jsonObject里原生的方法了,不过我们可以继承jsonObject类并且添加一个方法,利用反射,将json字符串转化成对象,这个继承的类如下

 

 

 
  1. package com.example.http_test;

  2.  
  3. import java.lang.reflect.Field;

  4.  
  5. import org.json.JSONObject;

  6.  
  7. public class SituJsonObject extends JSONObject {

  8. public SituJsonObject(String jsonString) throws Exception{

  9. super(jsonString);

  10. }

  11.  
  12. /**

  13. * 将一个json字符串转换成一个java类的实例

  14. * @param cls

  15. * @return

  16. * @throws Exception

  17. */

  18. public Object getBean(Class cls) throws Exception

  19. {

  20. //生成待输出的实例

  21. Object obj = cls.newInstance();

  22. //得到所有的成员变量

  23. Field[] fs = cls.getDeclaredFields();

  24. //对每个成员变量,从json字符串中取值,并且放到实例中

  25. for (int i = 0; i < fs.length; i++) {

  26. String name = fs[i].getName();

  27. fs[i].setAccessible(true);//防止私有成员不能访问

  28. //从json中获取这个属性所对应的值

  29. Object value = this.get(name);

  30. if(value==null)continue;

  31. //把当前的成员变量值放到实例中

  32. fs[i].set(obj, value);

  33. }

  34. return obj;

  35. }

  36. }

 

有了这个,就比原来的jsonObject类多了一个getBean方法,只需要传入一个class文件即可

注意:传入的class不能为内部类!!!

注意:传入的class不能为内部类!!!

注意:传入的class不能为内部类!!!

重要的事情说三遍,下面来简单的测试一下:

先写个简单的java类

注:不需要java类里有get、set方法

 

 
  1. public class Person {

  2. String name;

  3. int age;

  4. }

 

 

 

 
  1. SituJsonObject situJsonObject = null;

  2. try {

  3. situJsonObject = new SituJsonObject("{name:'jack',age:12}");

  4. } catch (Exception e) {

  5. // TODO Auto-generated catch block

  6. e.printStackTrace();

  7. System.out.println("json字符串格式错误");

  8. }

  9.  
  10. Person p;

  11. try {

  12. p = (Person) situJsonObject.getBean(Person.class);

  13. System.out.println("person是"+p.name+p.age);

  14. } catch (Exception e) {

  15. // TODO Auto-generated catch block

  16. e.printStackTrace();

  17. System.out.println("不能解析");

  18. }


如果json字符串格式不出错的话,应该很容就成功了,注意int类型的在json字符串里不要加双引号,这个原生类还不能自动进行parseInt;

 

原生还有一个jsonArray,里面一个常用的功能是get(下标),用来取出这个数组对应下标的值(object)

我们也添加两个方法,用来获取对应的java类

 

 

 
  1. package com.example.http_test;

  2.  
  3. import org.json.JSONArray;

  4. import org.json.JSONException;

  5. import org.json.JSONObject;

  6.  
  7. public class SituJsonArray extends JSONArray {

  8. public SituJsonArray(String Jsons) throws JSONException

  9. {

  10. super(Jsons);

  11. }

  12.  
  13. /**

  14. * 从这个数组里根据下标返回一个JSONObject对象

  15. * @param index

  16. * @return

  17. * @throws Exception

  18. */

  19. public JSONObject getJsonObject(int index) throws Exception

  20. {

  21. return new SituJsonObject(get(index).toString());

  22. }

  23.  
  24. /**

  25. * 通过下标返回一个java类对象,实际上就是用上一个自定义类嵌套使用

  26. * @param index

  27. * @param cls

  28. * @return

  29. * @throws JSONException

  30. * @throws Exception

  31. */

  32. public Object getObject(int index, Class cls) throws JSONException, Exception

  33. {

  34. return new SituJsonObject(get(index).toString()).getBean(cls);

  35. }

  36.  
  37. }

 

有了这个,稍微遍历一下就可以把json数组里的每个类一个一个的取出来,不过条件是这个数组里只能存放一种类型的对象,下面做个测试

 

 
  1. //json数组的解析

  2. SituJsonArray situJsonArray = null;

  3. try {

  4. situJsonArray = new SituJsonArray("[{name='one',age=20},{name='two',age=30}]");

  5. } catch (JSONException e) {

  6. // TODO Auto-generated catch block

  7. e.printStackTrace();

  8. System.out.println("json字符串格式错误");

  9. }

  10. try {

  11. //得到单个的jsonObject对象

  12. System.out.println(situJsonArray.getJsonObject(0));

  13. System.out.println(situJsonArray.getJsonObject(1));

  14. //得到java对象

  15. System.out.println(situJsonArray.getObject(0,Person.class));

  16. System.out.println(situJsonArray.getObject(1,Person.class));

  17. } catch (Exception e) {

  18. // TODO Auto-generated catch block

  19. e.printStackTrace();

  20. System.out.println("解析失败");

  21. }

 

那么如何用JsonObject生成一个json字符串,答案是只能一个属性一个属性的往上put,jsonObject也没有提供普通类转json的方法

如下:

 

 
  1. JSONObject jsonObject = new JSONObject();

  2. try {

  3. jsonObject.put("name", "jack");

  4. jsonObject.put("age", 12);

  5. } catch (JSONException e) {

  6. // TODO Auto-generated catch block

  7. e.printStackTrace();

  8. }

  9. System.out.println(jsonObject.toString());

  10. }


输出结果:{"age":12,"name":"jack"}

那么按照刚才的思路,在我们自定义的SituJsonObject上加一个方法,用反射来写一个类所有的成员,不妨这个类叫writeBean

注:这个方法不需要java类里有get、set方法

 
  1. public void writeBean(Object obj) throws IllegalAccessException, IllegalArgumentException, JSONException{

  2. Class cls = obj.getClass();

  3. Field[] fs = cls.getDeclaredFields();

  4. //对每个成员变量,从json字符串中取值,并且放到实例中

  5. for (int i = 0; i < fs.length; i++) {

  6. String name = fs[i].getName();

  7. fs[i].setAccessible(true);//防止私有成员不能访问

  8. Object value = fs[i].get(obj);//从传入对象中取得相应的值

  9. this.put(name, value);

  10. }

  11. }


来做一下简单的写入测试:

 

 
  1. SituJsonObject situJsonObject = new SituJsonObject();

  2. try {

  3. situJsonObject.writeBean(new Person("lixiao", 14));//只需要这一句话就把所有的成员写到JsonOBject对象里去了,不需要一个一个put了

  4. System.out.println(situJsonObject.toString());

  5. } catch (IllegalAccessException | IllegalArgumentException

  6. | JSONException e) {

  7. // TODO Auto-generated catch block

  8. e.printStackTrace();

  9. System.out.println("反射失败");

  10. }


测试结果:{"age":14,"name":"lixiao"}

如果想生成json字符串数组,只要把单个对象的json字符串简单相加就好了,不需要使用JSONArray类

我们在jsonObject里面再加一个方法,就叫getArrayString吧,接受一个list<Object>作为参数,利用之前写好的writeBean,把每个json字符串拼接起来,直接返回一个可用的字符串

 

 
  1. public String getArrayString(List<Object> list) throws IllegalAccessException, IllegalArgumentException, JSONException{

  2. StringBuffer sBuffer = new StringBuffer();

  3. sBuffer.append("[");

  4. for (Object object : list) {//把每个对象的json字符串拼接起来

  5. SituJsonObject situJsonObject = new SituJsonObject();

  6. situJsonObject.writeBean(object);

  7. sBuffer.append(situJsonObject.toString()).append(",");

  8. }

  9. sBuffer.deleteCharAt(sBuffer.length()-1);//去掉最后面的逗号

  10. sBuffer.append("]");

  11. return sBuffer.toString();

  12. }

 

结果是:[{"age":10,"name":"wang"},{"age":10,"name":"wang"},{"age":10,"name":"wang"},{"age":10,"name":"wang"},{"age":10,"name":"wang"},{"age":10,"name":"wang"},{"age":10,"name":"wang"},{"age":10,"name":"wang"}]

 

 

安卓原生的这两个类在修改过后,在一些简单场合下使用起来还是不错的,不过笔者更推荐使用阿里巴巴的fastjson类,这个jar包有单独为android出的版本,兼容性很好,而且使用起来的感觉和json-lib差不多,最可贵的是这个类号称比jackJson的速度都快,而且不需要依赖包,十分小巧轻便,本人的博客上传了,地址是http://download.csdn.net/detail/lvshaorong/9187375,是目前安卓这边的最新版本

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值