1. 程式人生 > >GSON轉換報錯

GSON轉換報錯

關於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,然後使用,就不會報錯了。