web-URL参数解析

Posted woxiaohaha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web-URL参数解析相关的知识,希望对你有一定的参考价值。

需求:  对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提取

以上是关于web-URL参数解析的主要内容,如果未能解决你的问题,请参考以下文章

在模拟器中正常,但在 ios 设备中抛出异常

无法解析片段中的 findViewById [重复]

无法解析片段中的 ViewModelProvider 构造?

Relay.js 没有正确解析组合片段

Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段

从 XML 声明片段获取 XML 编码:部分内容解析不支持 XmlDeclaration