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