【我的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]
如果本文對您有所幫助,歡迎您掃碼下圖所示的支付寶和微信支付二維碼對本文進行打賞。