需求: 对URL进行去重,去掉所有的参数中value内容,只保留path和key
解决方案:
1. 首先根据 分号字符(?) 分割出path和param
2. 然后在对param进行解析,使用&进行分割,获得每个itema
3. 最后对itema使用=进行分割,保留key
4. 最后拼接path和key获得唯一字符串 ,为一个url的唯一标志
但后来发现一些不符合预期的结果,比如使用jsonp的调用,参数中是存在任意字符的。形如:a={"c":[{"d":"8&6"}]}&b=2 ,导致解析失败
最后发现只能通过逐字符解析,才能解决这个问题。
具体实现:
1. 进行URL解码,若解码失败,对关键字符 %7B -> {, %7D -> }, %20 -> 空
2. 初始化iFlag=0, key =‘‘, val= ‘‘, strSplit= ‘/‘ #key之间分隔符,strKey = ‘‘ #记录所有key的结果
3. 获得一个字符 item,下标 i
4. if iFlag > 0:
if iFlag == 1: value 起始位置
iStartDakuohao = i
if iFlag == 1 && item == ‘ ‘: #跳过空格
continue
if iFlag == 1&& item == ‘{‘:
iFlag = 2
iCountDakuohao = 1
iStarDakuohao = i //重新定义jsonp的开始位置
continue
if iCountDakuohao > 0:
if item == ‘}‘:
iCountDakuohao --
if iCountDakuohao == 0:
strTmp = jsondata
list jsondata
else if item == ‘{‘:
iCountDakuohao ++
else if item == ‘&‘ #普通形式的value结尾
iFlag = 0
else
val.add(item)
else if key.len == 0 && item == ‘‘ continue #过滤掉 开始的空白符 比如 a=1& b=2
if item == ‘=‘ { iFlag =1; #表示已经获得key
if key != ‘_‘:
strKey = strKey + key + strSplit
key = ‘‘
}
else {
if item == ‘&‘: #过滤掉没有值得key 比如 a&b=1
key = ‘‘
else:
key.add(item) #key里面增加一个字符
}
样例代码:
private static String getAllKeyList(String str,String strSplit) throws UnsupportedEncodingException { String strKey = ""; StringBuffer key = new StringBuffer(); StringBuffer val = new StringBuffer(); int iFlag = 0; int iCountDakuohao = 0; int iStartDakuohao = 0; try { str = java.net.URLDecoder.decode(str, "utf-8"); }catch (Exception exp){ if(str.indexOf("%7B") > -1){ str = str.replace("%7B", "{");// } if(str.indexOf("%7D") > -1){ str = str.replace("%7D", "}"); } if(str.indexOf("%20") > -1){ str = str.replace("%20"," "); } } for (int i = 0; i < str.length(); i++) { char item = str.charAt(i); if(iFlag > 0){ //跳过= 与{之间空格, 兼容不是jsonp 保留value最开始位置 if(iFlag == 1){ //value起始位置 iStartDakuohao = i; } if(iFlag == 1 && item == ‘ ‘){ continue; } if(item == ‘{‘ && iFlag == 1){ iFlag = 2; iCountDakuohao = 1; iStartDakuohao = i; //jsonp开始位置 重新定义 continue; } if(iCountDakuohao > 0){ if(item == ‘}‘){ iCountDakuohao--; if(iCountDakuohao == 0){ String strTmp = str.substring(iStartDakuohao, i+1); try{ if(strTmp.indexOf("%22") > -1){ strTmp = strTmp.replace("%22", "\""); } if(strTmp.indexOf("\\x5C") > -1){ strTmp = strTmp.replace("\\x5C","\\"); } if(strTmp.indexOf("\\x22") > -1){ //强制转换 \x22 strTmp = strTmp.replace("\\x22", "\""); } JSONObject obj = JSONObject.fromObject(strTmp); Iterator iterator = obj.keys(); while (iterator.hasNext()){ String t = (String) iterator.next(); strKey = strKey + t + strSplit; //获得json中value // System.out.println(obj.get(t)); } // end while }catch (Exception exp){ System.out.println(exp.getMessage()); } // System.out.println(Integer.toString(iStartDakuohao) + "---" + strTmp + " --- " + Integer.toString(i)); } }else if(item == ‘{‘){ iCountDakuohao++; } continue; } if(item == ‘&‘) { // bFindKey = false; iFlag = 0; //获得value // System.out.println(str.substring(iStartDakuohao, i)); }else val.append(item); }else { // 过滤掉 a=1& m=2 if(key.length() == 0 && item == ‘ ‘) continue; if (item == ‘=‘) { // bFindKey = true; iFlag = 1; String strTmp = key.toString(); if(!strTmp.equals("_")) strKey = strKey + strTmp + strSplit; key.setLength(0); } else { if(item == ‘&‘) //过滤掉 没有值的key 比如 a&b=1 key.setLength(0); else key.append(item); } } if( i == str.length() -1){ //输出最后一个value // System.out.println(str.substring(iStartDakuohao, i+1)); } } return strKey; // System.out.println(strKey); } String str = "param= {\"a\":1}&d& m= 78&_=1234"; System.out.println(getAllKeyList(str,"/")); |
|
一个bug,只能解析一级json,不能进行多级json提取