android解析JSON数据

时间:2022-07-03 08:35:27

jsonobject的使用

 一、 json对象的使用:

?
1
2
3
4
string content = "{'username': 'linux', 'password': '123456'}";
jsonobject jsonobject = new jsonobject(content);
string username = jsonobject.getstring("username");
string password = jsonobject.getstring("password");

 

二、 json数组的使用:

?
1
2
3
4
5
6
7
8
9
10
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对象混合使用

?
1
2
3
4
5
6
7
8
9
10
11
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数组中存储对象

?
1
2
3
4
5
6
7
8
9
10
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:

?
1
2
3
4
private final linkedhashmap<string, object> namevaluepairs;
public jsonobject() {
  namevaluepairs = new linkedhashmap<string, object>();
}

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

?
1
2
3
4
public jsonobject put(string name, boolean value) throws jsonexception {
  namevaluepairs.put(checkname(name), value);
  return this;
}

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

?
1
2
3
4
5
6
7
8
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类型的参数

?
1
2
3
public jsonobject(string json) throws jsonexception {
  this(new jsontokener(json));
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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()方法,逐个得到解析的字符,下到解析到}.下面贴出重要代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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方法,针对一些类型做处理,得到解析之后的结果:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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:

?
1
2
3
4
5
6
7
8
9
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类,方便测试:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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格式

?
1
2
3
4
5
6
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格式解析成对象

?
1
2
3
string jsondata = "{'name':'刘力','age':19}";
person person = gson.fromjson(jsondata, person.class);
system.out.println(person.getname() + ", " + person.getage());

打印结果: 刘力, 19

四、 gson把list对象解析成json格式:

?
1
2
3
4
5
6
7
8
9
10
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对象:

?
1
2
3
4
5
6
7
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