android解析JSON数据

作者:hebedich 时间:2022-10-17 04:55:40 

JSONObject的使用

 一、 JSON对象的使用:


String content = "{'username': 'linux', 'password': '123456'}";
JSONObject jsonObject = new JSONObject(content);
String username = jsonObject.getString("username");
String password = jsonObject.getString("password");

二、 JSON数组的使用:


String jsonContent = "[{'user': '刘力', 'age': 21, 'femal': true}, "
           + "{'user': 'chen', 'age': 20, 'femal': false}]";
JSONArray jsonArray = new JSONArray(jsonContent);
for (int i = 0; i < jsonArray.length(); i++) {
  JSONObject object = jsonArray.getJSONObject(i);
  System.out.print(object.getString("user") + " ");
  System.out.print(object.getInt("age") + " ");
  System.out.print(object.getBoolean("femal") + " ");
  System.out.println();
}

三、 JSON数组与JSON对象混合使用


String jsonString = "[{'user': 'tomhu', 'age': 21, " + "'info': {'adress': 'hubai', 'sex': 'femal'}}, "
         + "{'user': 'chen', 'age': 20, " + "'info': {'adress': 'hunan', 'sex': 'male'}}]";
JSONArray jsonArrays = new JSONArray(jsonString);
for (int i = 0; i < jsonArrays.length(); i++) {
 JSONObject objects = jsonArrays.getJSONObject(i);
 System.out.print(objects.getString("user") + " ");
 System.out.print(objects.getInt("age") + " ");
 System.out.print(objects.getJSONObject("info").getString("adress") + " ");
 System.out.print(objects.getJSONObject("info").getString("sex") + " ");
 System.out.println();
}

四、 JSON数组中存储对象


Person person = new Person();
person.setUsername("linux" );
person.setPassword("123456" );
JSONArray jsonArray = new JSONArray();
jsonArray.put(0, person );
jsonArray.put(1, "I love you" );

// String username = jsonArray.getJSONObject(0).getString("username"); 错误的写法
Person user = (Person) jsonArray.get(0);
System.out.println("username: " + user.getUsername());

JSONObject的原理

JsonObject的存储与取出

一、 JSONObject里面维护了一个LinkedHashMap,当生成一个无参数的JSONObject,实质是初始化了一个Map:


private final LinkedHashMap<String, Object> nameValuePairs;
public JSONObject() {
 nameValuePairs = new LinkedHashMap<String, Object>();
}

 二、 当JSONObject增加数据,实质上把数据的键值对方法存放在上述的Map中:


public JSONObject put(String name, boolean value) throws JSONException {
 nameValuePairs.put(checkName(name), value);
 return this;
}

三、 从JSONObject中取出数据,很容易想到的就是从Map取出了:


public String getString(String name) throws JSONException {
 Object object = get(name); // get()方法就是执行Object result = nameValuePairs.get(name);
 String result = JSON.toString(object);
 if (result == null) {
   throw JSON.typeMismatch(name, object, "String");
 }
 return result;
}

JsonObject的解析过程

一、 JsonObject还有一个带参数的构造函数:常用的是传递一个String类型的参数


public JSONObject(String json) throws JSONException {
 this(new JSONTokener(json));
}

二、 跟进去,发现主要执行的是JSONTokener的nextValue()方法,在这个方法中主要是对数据进行解析;


public Object nextValue() throws JSONException {
 int c = nextCleanInternal();
 switch (c) {
   case -1:
     throw syntaxError("End of input");

case '{':
     return readObject();

case '[':
     return readArray();

case '\'':
   case '"':
     return nextString((char) c);

default:
     pos--;
     return readLiteral();
 }
}

在nextCleanInternal方法中,它会从头到尾的逐个字符的解析,对于一些字符做一些处理。例如空格,换行,转义符等!
当解析到[表示开始一个对象的读取,当解析到{表示一个数组的读取

三、 在readObject方法中,仍然是调用nextCleanInternal()方法,逐个得到解析的字符,下到解析到}.下面贴出重要代码


int first = nextCleanInternal(); // 得到解析的字符
if (first == '}') {
 return result;
} else if (first != -1) {
 pos--;
}
.......
while (true) {
 Object name = nextValue(); // 解析得到键

int separator = nextCleanInternal();
 if (separator != ':' && separator != '=') {
   throw syntaxError("Expected ':' after " + name);
 }
 if (pos < in.length() && in.charAt(pos) == '>') {
   pos++;
 }

result.put((String) name, nextValue()); // 将解析得到的键值对,存放在map当中

switch (nextCleanInternal()) {
   case '}':
     return result;
   case ';':
   case ',':
     continue;
   default:
     throw syntaxError("Unterminated object");
 }
}

四、 nextValue方法比较关键,它流转解析的大部分工作!在nextValue中有一个readLiteral方法,针对一些类型做处理,得到解析之后的结果:


private Object readLiteral() throws JSONException {
 String literal = nextToInternal("{}[]/\\:,=;# \t\f");

if (literal.length() == 0) {
   throw syntaxError("Expected literal value");
 } else if ("null".equalsIgnoreCase(literal)) {
   return JSONObject.NULL;
 } else if ("true".equalsIgnoreCase(literal)) {
   return Boolean.TRUE;
 } else if ("false".equalsIgnoreCase(literal)) {
   return Boolean.FALSE;
 }

/* try to parse as an integral type... */
 if (literal.indexOf('.') == -1) {
   int base = 10;
   String number = literal;
   if (number.startsWith("0x") || number.startsWith("0X")) {
     number = number.substring(2);
     base = 16;
   } else if (number.startsWith("0") && number.length() > 1) {
     number = number.substring(1);
     base = 8;
   }
   try {
     long longValue = Long.parseLong(number, base);
     if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
       return (int) longValue;
     } else {
       return longValue;
     }
   } catch (NumberFormatException e) {
     /*
      * This only happens for integral numbers greater than
      * Long.MAX_VALUE, numbers in exponential form (5e-10) and
      * unquoted strings. Fall through to try floating point.
      */
   }
 }

/* ...next try to parse as a floating point... */
 try {
   return Double.valueOf(literal);
 } catch (NumberFormatException ignored) {
 }

/* ... finally give up. We have an unquoted string */
 return new String(literal); // a new string avoids leaking memory
}

五、至于JSONArray的解析与JsonObject的解析过程是一样的,它里面维护的是一个List:


private final List<Object> values;
public JSONArray(JSONTokener readFrom) throws JSONException {
 Object object = readFrom.nextValue();
 if (object instanceof JSONArray) {
   values = ((JSONArray) object).values;
 } else {
   throw JSON.typeMismatch(object, "JSONArray");
 }
}

Gson的使用

一、我们在测试当中先加入一个Person类,方便测试:


package com.tomhu.test;

public class Person {
 private String name;
 private int 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;
 }
}

二、 gson把对象转换成JSON格式


Gson gson = new Gson();
Person person = new Person();
person.setName("linux");
person.setAge(23);
String str = gson.toJson(person);
System.out.println(str);

打印结果:  {"name":"linux","age":23}

三、 gson把json格式解析成对象


String jsonData = "{'name':'刘力','age':19}";
Person person = gson.fromJson(jsonData, Person.class);
System.out.println(person.getName() + ", " + person.getAge());

打印结果: 刘力, 19

四、 gson把List对象解析成Json格式:


Gson gson = new Gson();
List<Person> persons = new ArrayList<Person>();
for (int i = 0; i < 2; i++) {
  Person p = new Person();
  p.setName("name" + i);
  p.setAge(i * 5);
  persons.add(p);
}
String str = gson.toJson(persons);
System.out.println(str);

打印结果: [{"name":"name0","age":0},{"name":"name1","age":5}]

五、 gson把Json格式解析成List对象:


Gson gson = new Gson();
String str = "[{'name':'linux','age':10},{'name':'huhx','age':22}]";
List<Person> ps = gson.fromJson(str, new TypeToken<List<Person>>(){}.getType());
for (int i = 0; i < ps.size(); i++) {
 Person person = ps.get(i);
 System.out.print("name: " + person.getName() + " age: " + person.getAge());
}

打印结果:name: linux age: 10 name: huhx age: 22

标签:android,解析JSON数据
0
投稿

猜你喜欢

  • Android基础之startActivityForResult()的用法详解

    2022-05-28 03:37:29
  • Android自定义控件实现圆形进度条

    2023-02-02 05:01:59
  • 新手小白看过来学JAVA必过IO流File字节流字符流

    2022-09-22 07:42:02
  • Android 中倒计时验证两种常用方式实例详解

    2022-08-29 04:44:41
  • Spring Cloud Gateway重试机制的实现

    2023-11-06 01:32:59
  • 教你怎么用idea创建web项目

    2021-12-23 14:45:16
  • Mybatis在sqlite中无法读写byte[]类问题的解决办法

    2021-08-06 21:06:07
  • Android实现环形进度条的实例

    2023-01-11 17:39:22
  • javaWeb项目部署到阿里云服务器步骤详解

    2023-11-07 05:21:36
  • C语言数据结构系列篇二叉树的遍历

    2023-12-28 03:19:03
  • Android实现点击图片上传SQLite数据库

    2021-06-23 04:35:50
  • C++实现扫雷小游戏

    2022-07-27 22:59:39
  • SpringBoot项目在IntelliJ IDEA中如何实现热部署

    2023-10-29 13:30:22
  • C#实现窗体全屏的两种方法

    2021-10-06 19:14:04
  • Java sha1散列算法原理及代码实例

    2021-06-28 05:50:22
  • Spring中Bean扫描原理详情

    2022-05-26 04:33:14
  • C#实现简单合并word文档的方法

    2022-10-27 10:50:00
  • 分析设计模式之模板方法Java实现

    2022-01-20 21:02:22
  • insert语句太长用StringBuilder优化一下

    2023-03-29 17:56:44
  • SpringBoot Admin 如何实现Actuator端点可视化监控

    2022-12-09 01:40:51
  • asp之家 软件编程 m.aspxhome.com