? ? ? 最近项目中用到json这个数据结构,由于jdk1.6并没有提供默认解析json的api,项目中选用了apache的json工具类来做解析,目前常用的json解析工具还有google提供的gson和阿里的fastjson。
? ? ? 网上瞅了半天,想了下,json解析无非是对字符串做遍历,忍不住自己尝试解析下,通过递归实现一次字符串的完整遍历来完成json字符串与Map的转换。
? ? ? 首先列出json中常用的几个特殊字符:' " : [ ] { }。
java解析json过程中,需要考虑{}和[]之间的嵌套,同时当前被解析节点的是在map还是list中,如:
class="java" name="code">{'_key1':'_v1','_key2':'_v2'} //其中_key1、_v1、_key2、_v2都是在map中。
?而
{'_list':['a','b']} //a、b都是位于list中,而['a','b']则在map中。
?
实现方法:顺序解析json字符串,当遇到{}或[]时递归调用当前方法,递归完成之后将字符串搜索的位置移动到]或}处继续遍历。
代码如下:
?
package com.json; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; @SuppressWarnings({"unchecked","rawtypes"}) public class JSON2Map{ private static final Logger log = Logger.getLogger("parse"); public static Map getMap(String json){ return parse(json); } public static Map parse(String json){ if(json == null){ log.error("json is null."); } HashMap jsonObj = new HashMap(); json = json.trim(); if(json.startsWith("{")){ parse(json.substring(1), jsonObj, true); } return jsonObj; } public static int parse(String json, Object obj, boolean isMap){ /* json: 待解析的json字符串 obj :当前json串的父节点 isMap: 当前解析的json串是位于map中还是list中。 */ HashMap jsonObject = null; ArrayList jsonArray = null; int word_s_position = 0; int word_e_position = 0; String word = ""; //'或"分隔符是一个单词开头还是结尾 boolean isStart = true; //当前值是json的key还是value boolean isKey = true; if(isMap){ jsonObject = (HashMap) obj; } else { jsonArray = (ArrayList) obj; } int len = json.length(); char current_char = ' '; for(int x=0; x<len; x++){ current_char = json.charAt(x); switch(current_char){ case '\'': case '\"': if(isStart) { word_s_position = x+1; isStart = false; } else { word_e_position = x; if(isMap){ //父节点为map if(isKey){ //当前为key word = json.substring(word_s_position, word_e_position); log.debug("current is key, the value is: >>>> "+word); jsonObject.put(word, null); } else { log.debug("current is value, the value is: >>>> "+json.substring(word_s_position, word_e_position)); jsonObject.put(word, json.substring(word_s_position, word_e_position)); isKey = true; } } else { jsonArray.add(json.substring(word_s_position, word_e_position)); } isStart = true; } break; case '{' : HashMap _jsonObj = new HashMap(); if(isMap){ jsonObject.put(word, _jsonObj); } else { jsonArray.add(_jsonObj); } int pass_obj_char = parse(json.substring(x+1), _jsonObj, true); x += pass_obj_char; log.debug("current parsing json string is : "+ json); log.debug("parsed json string is: " + json.substring(0, x)); log.debug("remain to parsing json string is:"+json.substring(x+1)); break; case '[' : ArrayList _jsonArray = new ArrayList(); if(isMap){ jsonObject.put(word, _jsonArray); } else { jsonArray.add(_jsonArray); } int pass_array_char = parse(json.substring(x+1), _jsonArray, false); x += pass_array_char; log.debug("current parsing json string is : "+ json); log.debug("parsed json string is: " + json.substring(0, x)); log.debug("remain to parsing json string is:"+json.substring(x+1)); break; case '}' : //结束当前map return x+1; case ']' : //结束当前list return x+1; case ',' : if(isMap){ isKey = true; } else { isKey = false; } break; case ':' : isKey = false; break; } } return json.length(); } }
?调用方法
String json = "{'abc':'ac','acb':'ae','arr1':[{'subArr1':{'abc':'ac','acb':'ae','arr1':[{'subArr1':'subArr2'},{'subArr2':'subArr3'}]}},{'subArr2':'subArr3'}],'key2':'value2','et':{'ab':'er','a':'re'},'key1':'value1'}"; Map map = JSON2Map.getMap(json); log.debug(map);
?