前段时间遇到把json数据转成java对象的问题,网上有很多的jar包可以直接使用,但是总感觉很庞大,许多功能用不上,因此着手写了个简单的处理方法。主要采用栈的思想实现对json字符串解析。这里提供的方法没有对json字符串进行校验,只有保证传入的json字符串是正确的格式,函数才会返回正确的执行结果。函数运行到最后如果栈非空,则表明json字符串不满足本函数所能识别的json格式或则该字符串本身就不是正确的json格式。
定义基本的键值对象,用于表示JSON数据最基本元素类型
public calss KV{
private String key;
private String value;
}
定义JSON数据对象,用于保存识别成对象的JSON数据
public class Json {
private String name;
private List<KV> data;
private Json parent;
private List<Json> children;
private String Type;// root,array_object,data_object
}
在JSON对象中,我采用Type来区分JSON的元素是一个数组(array_object)、或则一个包含多个子元素的JSON对象(data_object),并采用root类型做为JSON对象的根节点。其中把基本的子集KV数据存放在data链表中,把复杂的键值数据存在children链表中,并设置一个指定其父级的指针parent。
采用栈的方式处理JSON字符串
public Json jsonToMap(String json){
int top = -1; //stack top
char[] stack = new char[json.length()+1];
char[] js = json.toCharArray();
Json jsondata = null;
int count = 0;//计数‘"’出现的次数,用于控制取出key或value的值
for(int i=0; i<js.length; ++i){
stack[++top] =js[i];
if(stack[top] =='{' ){
//--//System.out.println("->child");
if(jsondata == null){
jsondata = new Json();
jsondata.setParent(null);
jsondata.setType("root");
}else if(jsondata.getName() == null || stack[top-1] =='['){
Json jo = new Json();
jo.setParent(jsondata);
jo.setType("data_object");
if(jsondata.getChildren() == null){
jsondata.setChildren(new ArrayList<Json>());
}
jsondata.getChildren().add(jo);
jsondata = jo;
}else{
jsondata.setType("data_object");
}
//ischrild = true;
}else if(stack[top] =='['){
//--//System.out.println("->in array");
if(jsondata.getName() == null){
Json jo = new Json();
jo.setParent(jsondata);
jo.setType("array_object");
if(jsondata.getChildren() == null){
jsondata.setChildren(new ArrayList<Json>());
}
jsondata.getChildren().add(jo);
jsondata = jo;
}else{
jsondata.setType("array_object");
}
}else if(stack[top] =='}'){
if(jsondata.getParent() != null )
jsondata = jsondata.getParent();
//--//System.out.println("->parent");
}else if(stack[top] ==']'){
//--//System.out.println("->out array");
if(jsondata.getParent() != null )
jsondata = jsondata.getParent();
}
if(stack[top] == '"'){
count++;
}
if(count == 2 && stack[top] == '"') {
count = 0;
String data = "";
while(top > 0 && stack[--top] != '"'){
data = stack[top] + data;
}
--top;
if(jsondata.getData() == null){
jsondata.setData(new ArrayList<KV>());
}
if(js[i+1] == ':'){
//--//System.out.println(" key->" + data);
if(js[i+2] == '"') {
KV kv = new KV();
kv.setKey(data);
jsondata.getData().add(kv);
}else{
Json jo = new Json();
jo.setName(data);
jo.setParent(jsondata);
jo.setType("??");
if(jsondata.getChildren() == null){
jsondata.setChildren(new ArrayList<Json>());
}
jsondata.getChildren().add(jo);
jsondata = jo;
}
}else{
//--//System.out.println(" value->" + data);
jsondata.getData().get(jsondata.getData().size() -1).setValue(data);
}
}//if '"'
if(stack[top] == ':' && js[i-1] =='"'){
--top;
}
if(stack[top] == ',' &&
(js[i-1] =='}' || js[i-1] =='"' || js[i-1] == ']')){
--top;
}
if(top > 0 && stack[top] == '}' && stack[top-1] == '{'){
top -= 2;
}
if(top > 0 && stack[top] == ']' && stack[top-1] == '['){
top -= 2;
}
}//for
if(top != -1)
return null;
return jsondata;
}
这里提供一个简单的测试json字符串
String json = "{\"tree\":\"data1\",\"obj1\":{\"hello\":\"word\",\"in_obj2\":{\"lo\":\"wd\"}},\"obj2\":{\"2hello\":\"2word\"},"+
"\"shuzhu\":[{\"uid\":\"giggle\"},{\"lis\":\"echo helpp\"},{\"ren\":{\"baige\":\"haword\"},\"2\":{\"3\":\"4\"}}]}";
经验证,上述类型的json字符串是可以正常解析的。