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,然后使用,就不会报错了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值