GSON轉換報錯
阿新 • • 發佈:2019-01-06
關於GSON轉換時的JsonSyntaxException錯誤
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
今天在做Android接收伺服器回饋的資料轉義的時候突然報瞭如下的錯誤:
以下程式碼是我在Main出口模擬的一段
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang .IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:187)
at com.google.gson.Gson.fromJson(Gson.java:805)
at com.google.gson.Gson.fromJson(Gson.java :770)
at com.google.gson.Gson.fromJson(Gson.java:719)
at com.google.gson.Gson.fromJson(Gson.java:691)
at aaa.main(aaa.java:36)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java :387)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
... 5 more
而我的程式碼是這樣的:
public class aaa {
/**
* @param args
*/
public static void main(String[] args) {
Gson gson = new Gson();
// String a ="{success:false,msg:\u8d26\u53f7\u6216\u5bc6\u7801\u6709\u8bef}";
String json ="{success:false,msg:\u8d26\u53f7\u6216\u5bc6\u7801\u6709\u8bef}";
B bbb = gson.fromJson(json, B.class);
}
}
class B {
private boolean success;
private String msg;
private String ccc;
public B(){
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCcc() {
return ccc;
}
public void setCcc(String ccc) {
this.ccc = ccc;
}
@Override
public String toString() {
return "success="+success+";msg="+msg+";ccc="+ccc;
}
}
其中json中的欄位 是複製的伺服器回饋的內容,乍一看是沒什麼問題,格式也是json正常的格式,但是一轉義就開始報錯,我一直就不明白為什麼,於是我手寫了一段String a 一模一樣的程式碼,嘗試著運行了一下,沒有報錯!!是的 沒有報錯!
於是我開始對伺服器發來的json進行分解,先做了以下分解:
Gson gson = new Gson();
// String a = "{success:false,msg:\u8d26\u53f7\u6216\u5bc6\u7801\u6709\u8bef}";
String json ="{success:false,msg:\u8d26\u53f7\u6216\u5bc6\u7801\u6709\u8bef}";
// B bbb = gson.fromJson(a,B.class);
System.out.println(json);
String jj = "";
try {
jj = new String(json.getBytes("gbk"),"utf-8");
System.out.println(jj);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
我做了轉碼分析,隨便轉一個碼,結果發現很奇怪的事情:
{success:false,msg:賬號或密碼有誤}
????{success:false,msg:�˺Ż���������
這是打印出來的兩個結果,第一行是轉碼前,第二行是轉碼後,我們很清楚的看見前面還有一堆字元,但是在轉碼前 我們是看不到的
所以,我又對沒轉碼前的資料進行進一步的分析。
Gson gson = new Gson();
// String a = "{success:false,msg:\u8d26\u53f7\u6216\u5bc6\u7801\u6709\u8bef}";
String json ="{success:false,msg:\u8d26\u53f7\u6216\u5bc6\u7801\u6709\u8bef}";
// B bbb = gson.fromJson(a,B.class);
// System.out.println(json);
// String jj = "";
// try {
// jj = new String(json.getBytes("gbk"),"utf-8");
// System.out.println(jj);
// } catch (UnsupportedEncodingException e) {
// e.printStackTrace();
// }
System.out.println(json.startsWith("{"));
這次我做的是對“{”進行判斷,判斷是不是第一位:
false
列印的結果和逾期是一樣的,果真不是第一位…前面還藏著我們看不到的字元
這樣的話,就只有在Gson的工具類裡面多加一個方法進行判斷,無論是否是第一位都進行判斷
/**
* <br>對伺服器發來的json格式的資料進行格式修正
* <br>清除掉看不見的隱藏資料
* @param json
* @return
*/
public static String cleanErrorCode(String json){
if(!json.startsWith("{")){
json = json.substring( json.indexOf("{"),json.length());
}
if(!json.endsWith("}")){
json = json.substring(0,json.lastIndexOf("}")+1);
}
return json;
}
如此的話,問題就基本上解決了,無論伺服器傳過來什麼JSON資料,都進行一次clean,然後使用,就不會報錯了。