retrofit.RetrofitError:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期BEGIN_OBJECT但在第1行是STRING

时间:2015-11-13 01:50:01

标签: android gson retrofit

我得到一个非常奇怪的json,如下所示,gson无法以任何方式解析它。我试图将其作为列表捕获,因为它似乎是一个数组,但始终抛出异常

[{"Old":"1","New":"2","ConfirmNew":"2","Result":"succesfully completed","CustomProperties":{}},"eyJBY2Nlc3NUb2tlbiI6bnVsbCwiQ3VzdG9tZXJJRCI6NTc0Njc1LCJMYXN0QWNjZXNzVGltZSI6IlwvRGF0ZSgxNDQ3MzcyMjY3NjgxKVwvIiwiU2Vzc2lvbkd1aWQiOiIwZTkyNTY0YS05NzI1LTQ2MWEtOTMyYS03OTczZmMyYWJhN2QifQ=="]

这是我尝试解析的课程

@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);

2 个答案:

答案 0 :(得分:1)

你可以自定义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();

答案 1 :(得分:0)

似乎你将错误信息截断到它感兴趣的地方,即第1行中解析失败的字符位置。我的猜测是该位置是96 + -1。

[
    {
        "Old": "1",
        "New": "2",
        "ConfirmNew": "2",
        "Result": "succesfully completed",
        "CustomProperties": {}
    },
    "eyJBY2Nlc3NUb2tlbiI6bnVsbCwiQ3VzdG9tZXJJRCI6NTc0Njc1LCJMYXN0QWNjZXNzVGltZSI6IlwvRGF0ZSgxNDQ3MzcyMjY3NjgxKVwvIiwiU2Vzc2lvbkd1aWQiOiIwZTkyNTY0YS05NzI1LTQ2MWEtOTMyYS03OTczZmMyYWJhN2QifQ=="
]

我认为解析失败不是因为第一个元素,它确实是一个Object并且适合你的ChangePasswordResponseEntity,但是因为第二个元素是一个String。