retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1
retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1
我得到一个非常奇怪的 json 如下所示,gson 无法以任何方式解析它。我试图将它捕获为列表,因为它看起来是一个数组,但总是在
上方抛出异常
[{"Old":"1","New":"2","ConfirmNew":"2","Result":"succesfully completed","CustomProperties":{}},"eyJBY2Nlc3NUb2tlbiI6bnVsbCwiQ3VzdG9tZXJJRCI6NTc0Njc1LCJMYXN0QWNjZXNzVGltZSI6IlwvRGF0ZSgxNDQ3MzcyMjY3NjgxKVwvIiwiU2Vzc2lvbkd1aWQiOiIwZTkyNTY0YS05NzI1LTQ2MWEtOTMyYS03OTczZmMyYWJhN2QifQ=="]
这是我要解析的 class
@Getter
@Setter
@Accessors(fluent = true)
public class ChangePasswordResponseEntity {
@Expose
@SerializedName("Old")
private String Old;
@Expose
@SerializedName("New")
private String New;
@Expose
@SerializedName("ConfirmNew")
private String ConfirmNew;
@Expose
@SerializedName("Result")
private String Result;
@Expose
@SerializedName("CustomProperties")
private CustomProperties CustomProperties;
}
和改装方面
@POST("/ChangePassword/")
Observable<List<ChangePasswordResponseEntity>> changePassword(
@Body ChangePasswordRequestEntity changePasswordRequestEntity,
@Query(value = "signedRequest", encodeValue = false) String sessionID);
您似乎在错误消息变得有趣的地方截断了错误消息,即第 1 行中解析失败的字符位置。我的猜测是位置是96+-1.
[
{
"Old": "1",
"New": "2",
"ConfirmNew": "2",
"Result": "succesfully completed",
"CustomProperties": {}
},
"eyJBY2Nlc3NUb2tlbiI6bnVsbCwiQ3VzdG9tZXJJRCI6NTc0Njc1LCJMYXN0QWNjZXNzVGltZSI6IlwvRGF0ZSgxNDQ3MzcyMjY3NjgxKVwvIiwiU2Vzc2lvbkd1aWQiOiIwZTkyNTY0YS05NzI1LTQ2MWEtOTMyYS03OTczZmMyYWJhN2QifQ=="
]
我想解析失败不是因为第一个元素,它确实是一个对象并且确实适合你的ChangePasswordResponseEntity
,而是因为第二个元素,它是一个字符串。
您可以自定义 TypeAdapterFactory
。获取数组的第一个元素并丢弃其余元素。
public class PasswordResponseAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (typeToken.getType() != ChangePasswordResponseEntity.class) {
return null;
}
return (TypeAdapter<T>) newPasswordResponseAdapter(gson.getDelegateAdapter(this, TypeToken.get(ChangePasswordResponseEntity.class)));
}
private TypeAdapter<ChangePasswordResponseEntity> newPasswordResponseAdapter (final TypeAdapter<ChangePasswordResponseEntity> delegateAdapter) {
return new TypeAdapter<ChangePasswordResponseEntity>() {
@Override
public void write(JsonWriter out, ChangePasswordResponseEntity value) throws IOException {
delegateAdapter.write(out, value);
}
@Override
public ChangePasswordResponseEntity read(JsonReader in) throws IOException {
in.beginArray();
ChangePasswordResponseEntity response = delegateAdapter.read(in);
while(in.hasNext()) {
// Skip remaining elements in the array
in.skipValue();
}
in.endArray();
return response;
}
};
}
}
更改您的界面以仅查找 ChangePasswordResponseEntity
--
@POST("/ChangePassword/")
Observable<ChangePasswordResponseEntity> changePassword(
@Body ChangePasswordRequestEntity changePasswordRequestEntity,
@Query(value = "signedRequest", encodeValue = false) String sessionID);
与您的工厂一起制作自定义 gson --
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new PasswordResponseAdapterFactory())
.create();
创建 GsonConverterFactory
时使用新的 gson。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.example.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
// other settings ...
.build();
我得到一个非常奇怪的 json 如下所示,gson 无法以任何方式解析它。我试图将它捕获为列表,因为它看起来是一个数组,但总是在
上方抛出异常[{"Old":"1","New":"2","ConfirmNew":"2","Result":"succesfully completed","CustomProperties":{}},"eyJBY2Nlc3NUb2tlbiI6bnVsbCwiQ3VzdG9tZXJJRCI6NTc0Njc1LCJMYXN0QWNjZXNzVGltZSI6IlwvRGF0ZSgxNDQ3MzcyMjY3NjgxKVwvIiwiU2Vzc2lvbkd1aWQiOiIwZTkyNTY0YS05NzI1LTQ2MWEtOTMyYS03OTczZmMyYWJhN2QifQ=="]
这是我要解析的 class
@Getter
@Setter
@Accessors(fluent = true)
public class ChangePasswordResponseEntity {
@Expose
@SerializedName("Old")
private String Old;
@Expose
@SerializedName("New")
private String New;
@Expose
@SerializedName("ConfirmNew")
private String ConfirmNew;
@Expose
@SerializedName("Result")
private String Result;
@Expose
@SerializedName("CustomProperties")
private CustomProperties CustomProperties;
}
和改装方面
@POST("/ChangePassword/")
Observable<List<ChangePasswordResponseEntity>> changePassword(
@Body ChangePasswordRequestEntity changePasswordRequestEntity,
@Query(value = "signedRequest", encodeValue = false) String sessionID);
您似乎在错误消息变得有趣的地方截断了错误消息,即第 1 行中解析失败的字符位置。我的猜测是位置是96+-1.
[
{
"Old": "1",
"New": "2",
"ConfirmNew": "2",
"Result": "succesfully completed",
"CustomProperties": {}
},
"eyJBY2Nlc3NUb2tlbiI6bnVsbCwiQ3VzdG9tZXJJRCI6NTc0Njc1LCJMYXN0QWNjZXNzVGltZSI6IlwvRGF0ZSgxNDQ3MzcyMjY3NjgxKVwvIiwiU2Vzc2lvbkd1aWQiOiIwZTkyNTY0YS05NzI1LTQ2MWEtOTMyYS03OTczZmMyYWJhN2QifQ=="
]
我想解析失败不是因为第一个元素,它确实是一个对象并且确实适合你的ChangePasswordResponseEntity
,而是因为第二个元素,它是一个字符串。
您可以自定义 TypeAdapterFactory
。获取数组的第一个元素并丢弃其余元素。
public class PasswordResponseAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
if (typeToken.getType() != ChangePasswordResponseEntity.class) {
return null;
}
return (TypeAdapter<T>) newPasswordResponseAdapter(gson.getDelegateAdapter(this, TypeToken.get(ChangePasswordResponseEntity.class)));
}
private TypeAdapter<ChangePasswordResponseEntity> newPasswordResponseAdapter (final TypeAdapter<ChangePasswordResponseEntity> delegateAdapter) {
return new TypeAdapter<ChangePasswordResponseEntity>() {
@Override
public void write(JsonWriter out, ChangePasswordResponseEntity value) throws IOException {
delegateAdapter.write(out, value);
}
@Override
public ChangePasswordResponseEntity read(JsonReader in) throws IOException {
in.beginArray();
ChangePasswordResponseEntity response = delegateAdapter.read(in);
while(in.hasNext()) {
// Skip remaining elements in the array
in.skipValue();
}
in.endArray();
return response;
}
};
}
}
更改您的界面以仅查找 ChangePasswordResponseEntity
--
@POST("/ChangePassword/")
Observable<ChangePasswordResponseEntity> changePassword(
@Body ChangePasswordRequestEntity changePasswordRequestEntity,
@Query(value = "signedRequest", encodeValue = false) String sessionID);
与您的工厂一起制作自定义 gson --
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new PasswordResponseAdapterFactory())
.create();
创建 GsonConverterFactory
时使用新的 gson。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.example.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
// other settings ...
.build();