1. 程式人生 > >【我的Android進階之旅】關於解析json資料中自帶轉義符號的正確操作

【我的Android進階之旅】關於解析json資料中自帶轉義符號的正確操作

一、問題描述

在實現一個功能的時候,需要伺服器以json格式返回一段功能配置,比如如下所示的json配置。

1.1 我希望的json格式

{
  "k": "ClientFilterTrace_android",
  "isVisible": true,
  "description": "android大資料埋點過濾列表",
  "v": [
    {
      "functionName": "test_func1",
      "packageName": "com.oyp.csdn"
    },
    {
      "functionName": "test_func2"
, "packageName": "com.oyp.csdn" }, { "functionName": "test_func3", "packageName": "com.oyp.csdn" }, { "functionName": "test_func4", "packageName": "com.oyp.csdn" }, { "functionName": "test_func5", "packageName": "com.oyp.csdn" }, { "functionName
": "test_func6", "packageName": "com.oyp.csdn" } ]
}

這裡寫圖片描述

這裡寫圖片描述

1.2 伺服器返回自帶轉義符的json格式

然而,事與願違,我在SDK上已經將所有功能實現完,最後等將SDK整合到APP中,然後去獲取伺服器上的配置json的時候,發現APP解析失敗,然後認真檢視伺服器返回的json資料,發現居然預設自帶了轉義符號,如下所示:

{"k":"ClientFilterTrace_android","v":"[{\"functionName\":\"test_func1\",\"packageName\":\"com.oyp.csdn\"
},{\"functionName\":\"test_func2\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"test_func3\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"test_func4\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"test_func5\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"test_func5\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"test_func6\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"httpdns_info\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"Tab_More\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"bind_bindcode_bindnumber\",\"packageName\":\"com.oyp.csdn\"},{\"functionName\":\"bind_bindcode_bindnumber\",\"packageName\":\"com.oyp.csdn\"}]"}

這裡寫圖片描述

下面是兩種格式的對比圖

這裡寫圖片描述

二、解析json

2.1 不帶轉義符的json資料解析操作

我希望的格式的json對應的JavaBean類如下:

  • FilterFunctionConfig.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterFunctionConfig {
    private String k;
    private String isVisible;
    private String description;
    private List<FilterFunctionItem> v;

    public FilterFunctionConfig(){

    }

    public FilterFunctionConfig(String k){
        this.k = k;
    }

    public String getK() {
        return k;
    }

    public void setK(String k) {
        this.k = k;
    }

    public String isIsVisible() {
        return isVisible;
    }

    public void setIsVisible(String isVisible) {
        this.isVisible = isVisible;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<FilterFunctionItem> getV() {
        return v;
    }

    public void setV(List<FilterFunctionItem> v) {
        this.v = v;
    }

    @Override
    public String toString() {
        return "FilterFunctionConfig{" +
                "k='" + k + '\'' +
                ", isVisible=" + isVisible +
                ", description='" + description + '\'' +
                ", v=" + v +
                '}';
    }
}

這裡寫圖片描述

其中 FilterFunctionItem 類如下所示:

  • FilterFunctionItem.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterFunctionItem {
    /**
     * 需要過濾的functionName
     */
    private String functionName;
    /**
     * 需要過濾的packageName
     */
    private String packageName;


    public FilterFunctionItem() {

    }

    public FilterFunctionItem(String functionName) {
        this.functionName = functionName;
    }

    public FilterFunctionItem(String functionName, String packageName) {
        this.functionName = functionName;
        this.packageName = packageName;
    }

    public String getFunctionName() {
        return functionName;
    }

    public void setFunctionName(String functionName) {
        this.functionName = functionName;
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    @Override
    public String toString() {
        return "FilterFunctionItem{" +
                "functionName='" + functionName + '\'' +
                ", packageName='" + packageName + '\'' +
                '}';
    }
}

原來解析v得到List,程式碼如下:

  //轉換json字串為FilterInfoBean,然後取出List<FilterFunctionItem>
        FilterFunctionConfig config = JSONUtil.fromJSON(filterConfigJson, FilterFunctionConfig.class);
        List<FilterFunctionItem> list = new ArrayList<>();
        if (config != null) {
            list = config.getV();
        }
        LogUtil.d("getFilterFunctionItemList() 獲取到的list為:" + list);

我在SDK裡面的資料是不帶轉義符模擬伺服器返回的json資料,解析成功。

2.2 帶轉義符的json資料解析操作

但是伺服器返回的帶轉義符的json資料,從而解析失敗,因此我們需要修改FilterFunctionConfig類的定義。

修改如下:

  • FilterFunctionConfig.java
@JsonIgnoreProperties(ignoreUnknown = true)
public class FilterFunctionConfig {
    private String k;
    private String isVisible;
    private String description;
    private String v;

    public FilterFunctionConfig(){

    }

    public FilterFunctionConfig(String k){
        this.k = k;
    }

    public String getK() {
        return k;
    }

    public void setK(String k) {
        this.k = k;
    }

    public String getV() {
        return v;
    }

    public void setV(String v) {
        this.v = v;
    }

    public String getIsVisible() {
        return isVisible;
    }

    public void setIsVisible(String isVisible) {
        this.isVisible = isVisible;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "FilterFunctionConfig{" +
                "k='" + k + '\'' +
                ", isVisible=" + isVisible +
                ", description='" + description + '\'' +
                ", v='" + v + '\'' +
                '}';
    }
}

這裡寫圖片描述

這樣在解析伺服器返回的帶轉義符的json資料時,我們先將v解析成String,然後再解析v成List<FilterFunctionItem> ,如下所示:

List<FilterFunctionItem> list = new ArrayList<>();
        //讀取傳入進來的json配置,並解析
        FilterFunctionConfig config = JSONUtil.fromJSON(filterConfigJson, FilterFunctionConfig.class);
        LogUtil.d("saveFilterFunctionItemList() 解析出來的FilterFunctionConfig:" + config);
        if (config != null) {
            String v = config.getV();
            LogUtil.d("saveFilterFunctionItemList() 取出來的v :" + v);
            list = JSONUtil.toCollection(v, List.class, FilterFunctionItem.class);
        }
        LogUtil.d("saveFilterFunctionItemList() 獲取到的list為:" + list);

這裡寫圖片描述

如上所示,經過第一步解析成String之後,轉義符在String中預設被解析掉了,然後再解析成List的時候就成功了。

三、總結

建議一

可以直接將帶有轉義符的json資料解析成String,然後再對String進行其他解析操作,這樣對應的bean就可以按照上面寫的帶轉義符對應的javaBean格式來寫。

建議二

可以將帶有轉義符的json資料,先預處理去掉轉義符,然後再解析json。這樣對應的bean就可以按照上面寫的不帶轉義符對應的javaBean格式來寫。

比如,通過如下方式:

 // 從伺服器端獲取Json字串
        String jsonStr = "{\"k\":\"ClientFilterTrace_android\",\"v\":\"[{\\\"functionName\\\":\\\"test_func1\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"test_func2\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"test_func3\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"test_func4\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"test_func5\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"test_func5\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"test_func6\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"httpdns_info\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"Tab_More\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"bind_bindcode_bindnumber\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"},{\\\"functionName\\\":\\\"bind_bindcode_bindnumber\\\",\\\"packageName\\\":\\\"com.oyp.csdn\\\"}]\"}";
        // 宣告中間變數進行處理
        String jsonStrTmp = backlogJsonStr.replace("\\", "");
        //然後使用JsonUtil 工具類去對jsonStrTmp進行解析操作

☞ 本人QQ: 3024665621 ☞ QQ交流群: 123133153 ☞ github.com/ouyangpeng ☞ [email protected]

如果本文對您有所幫助,歡迎您掃碼下圖所示的支付寶和微信支付二維碼對本文進行打賞。

這裡寫圖片描述