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