JSON的使用、利用正則表達式解決不定類型返回Json格式

介紹

作爲移動端開發者,和服務器的通信是少不了了。下面我總結一我在開發中遇到有關json的問題

一般的Json

在我剛入門的時候,在公司的寫代碼當時的網絡返回也不復雜,10個字段以內,基本上熟悉Json的固定格式,手動寫Bean接收數據,只要用心字段名稱和類型對應就不會出問題。
推薦的Json格式校驗網站,http://json.parser.online.fr/

問題:就是如果字段複雜,就要花很多時間去校對字段,確認字段對象類型。

解決辦法

其實校驗Json格式這種沒什麼技術含量的事情,應該交給計算機去做。
所以網上有很多解決辦法

在線解析生成Bean對象

網站在這裏: http://www.bejson.com/json2javapojo/

GsonFormat插件

這是個一個能夠直接在Android Studio運行的插件。輸入Json字符串能夠直接生成bean對象

  • 安裝
    安裝如下圖:
    設置
    選擇 Plugins->搜索GsonFormat
    選擇
  • 使用
    快捷鍵 Alt+Instert 彈出GsonFormat
    複製Json字符串進去就OK了。

    不定格式的Json

    最近在寫個項目,接口來自其他公司網絡返回,有一個巨坑的問題,
    不定格式的Json內容。

  • 有時是avatar:{"對象類型"}

  • 有時是avatar:"String類型"
  • 其實就一個關鍵的url頭像地址最重要。如果是對象類型,對象中就包含一些圖片信息和url地址,如果是String類型就直接是一個url圖片地址。
    直接使用定義爲對象的話就會出現異常
    異常信息:參數異常,需要的解析的Bean該字段對應的是Object對象,但Json字符串中對應的是String對象。

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 14210 path $.pin.repins[1].user.avatar

非常非常的坑爹!!

思考

  • 從Json解析之後的Bean對象處理是不行的,因爲一開始的解析就報錯。
  • 想從Gson解析上看看有什麼特別的功能,從文檔上看沒有有效的解決辦法。有人找到的給個提示。

最終的解決辦法

正則表達式
在網絡數據還沒解析成Bean對象之前,處理成字符串,用正則對該字符串進行處理。

正則表達式,在網絡返回後將二進制流時轉換成字符串,正則表達式匹配查找取出其中url關鍵數據,替換統一成avatar:"String類型"

下面貼一部分實現代碼

說明:我的網絡訪問使用的是Retrofit,是Jack大神開發的REST風格的網絡訪問框架。以下代碼關鍵是在retrofit.Converter.Factory上得到二進制網絡返回體上做修改,其他網絡框架也可以,只要能到網絡訪問體即可。

網絡字節流轉字符串

  @Override
        public T convert(ResponseBody value) throws IOException {
            Reader reader = value.charStream();//取出字節流
            String result;
            try {
                BufferedReader in = new BufferedReader(reader);//讀取
                StringBuffer buffer = new StringBuffer();//構造buffer對象用於拼接
                String line;
                while ((line = in.readLine()) != null) {//讀行
                    buffer.append(line);//寫入buffer
                }
                result = buffer.toString();
            } finally {
                Utils.closeQuietly(reader);//記得關閉流
            }
            return gson.fromJson(regexChange(result), type);//返回解析後的對象
        }

正則表達式在Java的應用

 /**
         * 對輸入的字符串進行處理
         * @param input 傳入的需要處理的字符串
         * @return
         */
        private String regexChange(String input) {
            String result=input;
            //匹配規則是當avatar是{}包裝的對象
            Pattern mPAvatar=Pattern.compile("\"avatar\":\\{([^\\}]*)\\}");
            Matcher mMAvatar=mPAvatar.matcher(result);
            while (mMAvatar.find()){//如果找到 開始替換
                result=result.replaceFirst("\"avatar\":\\{([^\\}]*)\\}",getKey(mMAvatar.group()));
            }
            return result;
        }

/**
         * 取出關鍵值返回   
         * @param group
         * @return
         */
        private String getKey(String group) {
            Matcher matcher=mPkey.matcher(group);
            StringBuffer buffer=new StringBuffer();
             buffer.append("\"avatar\":\"http:///");
            while (matcher.find()){
                buffer.append(matcher.group(1));
            }
            buffer.append("\"");
            return buffer.toString();
        }

完美解決~~

另一種解決辦法

這在是一篇博客看到的,也是在Retrofit上應對不定格式的Json格式解析,思路也是在也是Converter.Factory的convert方法上做處理。思路是定義兩個不同的Bean類型,捕捉異常,做二次解析。不符合我的項目使用,只做介紹。
具體實現看博客:http://blog.csdn.net/efan006/article/details/50544204

總結

  1. 以上就是我對Json在Android編程中的一些理解和實際應用。
  2. 運用工具快速開發,把時間花在業務邏輯處理而不是重複的勞動。
  3. 對問題能夠換語言環境理解思考解決問題。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章