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