【问题标题】:retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但在第 1 行是 STRING
【发布时间】:2015-11-13 01:50:00
【问题描述】:

我得到了一个非常奇怪的 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);

【问题讨论】:

    标签: android gson retrofit


    【解决方案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();
    

    【讨论】:

      【解决方案2】:

      您似乎在有趣的地方截断了错误消息,即第 1 行中解析失败的字符位置。我的猜测是位置是96+-1。

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

      我想解析失败不是因为第一个元素,它确实是一个对象并且确实适合你的ChangePasswordResponseEntity,而是因为第二个元素,它是一个字符串。

      【讨论】:

      • 是的,我想是的,但我没有机会编辑 json。我实际上只需要那个“结果”参数,需要找到一种方法来获得它! :(
      猜你喜欢
      • 2021-11-17
      • 2020-03-10
      • 2020-01-29
      • 1970-01-01
      • 2015-11-06
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 1970-01-01
      相关资源
      最近更新 更多