当前位置: 首页 > 知识库问答 >
问题:

retrifit2-gson-预期的BEGIN_ARRAY但为STRING或预期的BEGIN_OBJECT但为BEGIN_ARRAY

慕俊迈
2023-03-14

我的Retrofit2调用出现以下异常:

retrofit = new Retrofit.Builder()
                .baseUrl(Constants.URL_HOST)
                .client(okHttpClient.build())
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

学分类别:

public class Credits {

    @SerializedName("director")
    @Expose
    private List<String> director;
    @SerializedName("actor")
    @Expose
    private List<String> actor = null;
    @SerializedName("presenter")
    @Expose
    private List<String> presenter;
    @SerializedName("commentator")
    @Expose
    private String commentator;

    public List<String> getDirector() {
        return director;
    }

    public void setDirector(List<String> director) {
        this.director = director;
    }

    public List<String> getActor() {
        return actor;
    }

    public void setActor(List<String> actor) {
        this.actor = actor;
    }

    public List<String> getPresenter() {
        return presenter;
    }

    public void setPresenter(List<String> presenter) {
        this.presenter = presenter;
    }

    public String getCommentator() {
        return commentator;
    }

    public void setCommentator(String commentator) {
        this.commentator = commentator;
    }
}

共有1个答案

秦钟展
2023-03-14

关于为什么会发生这个错误,你是对的。它试图解析一个数组,但接收到一个字符串。至于你的数据,最好还是坚持相同的模型。这意味着:使后端也返回一个数组,即使它只包含一个演示者。

然而,是的:我们可以用自定义类型适配器来修复这个问题。这个自定义类型适配器只需签入读取部分,不管它获取的是字符串还是数组。如果它得到一个字符串,我们将其重写为列表变体。

类型适配器

    null
    null

结果得到的类型适配器如下所示:

public class ListFromStringTypeAdapter extends TypeAdapter<List<String>> {

    public List<String> read(JsonReader reader) throws IOException {
        if (reader.peek() == JsonToken.NULL) {
            reader.nextNull();
            return null;
        }
        if (reader.peek() == JsonToken.STRING) {
            // ** This is the part where we fix the issue **
            // If we receive a String, get this and put it in a list.
            // Result will be that item in a list.
            List<String> list = new ArrayList<>();
            list.add(reader.nextString());
            return list;
        } else {
            // Else we expect to receive the array.
            // Based on original collection implementation:
            // https://github.com/google/gson/blob/0636635cbffa08157bdbd558b1212e4d806474eb/gson/src/main/java/com/google/gson/internal/bind/CollectionTypeAdapterFactory.java
            List<String> list = new ArrayList<>();
            reader.beginArray();
            while (reader.hasNext()) {
                String value = reader.nextString();
                list.add(value);
            }
            reader.endArray();
            return list;
        }
    }

    public void write(JsonWriter writer, List<String> list) throws IOException {
        // Simply writing the array, we don't need to modify anything here.
        // Based on original collection type adapter implementation:
        // https://github.com/google/gson/blob/0636635cbffa08157bdbd558b1212e4d806474eb/gson/src/main/java/com/google/gson/internal/bind/CollectionTypeAdapterFactory.java
        if (list == null) {
            writer.nullValue();
            return;
        }
        writer.beginArray();
        for (String string : list) {
            writer.value(string);
        }
        writer.endArray();
    }
}

将类型适配器注册为最后一个,我们需要告诉Gson将此类型适配器用于List类,因此修改创建Gson对象的位置:

// Get the type token for gson
Type collectionStringType = new TypeToken<List<String>>() {}.getType();
// Create gson object
Gson gson = new GsonBuilder()
        .registerTypeAdapter(collectionStringType, new ListFromStringTypeAdapter())
        .create();
 类似资料:
  • 问题内容: 我在列表中仅收到一个项目时收到此错误。我在服务器端REST Web服务中使用Jersey,当List返回一个元素并且当我得到它时,我仅收到错误,但是当它包含多个元素时,它可以正常工作,这就是我的工作方式它: 为什么Jersey不发送包含一个项目的列表?这是球衣的虫子吗?有没有办法使它始终序列化为数组? 当Web服务返回0元素时,这是我的JSON数据: 当Web服务返回1元素时,这是我的

  • 问题内容: 我在尝试将JSON解组到对象中时遇到GSON错误。错误( 应为BEGIN_OBJECT,但在第3行第22列处为STRING )指向下面输入的第3行。 我是否相对于Bean正确映射了JSON? 我输入的JSON看起来是这样的: 问题答案: 不,您没有正确映射它,因为您的json对象不是,它包含。 你可以创建一个类只是为了封装你,但它是清洁反序列化容器的使用 然后使用解析有趣的内容 并且我

  • 我试图使用gson解析下面的json字符串,并且我得到了这个异常。 异常很明显,它期待一个对象(可能是Datapoint),但它遇到了一个数组。我确信是我的模型类导致了这个问题,但是我不明白我的模型类应该是什么样子才能解析json而不会失败。

  • 我将请求映射到类,如下所示: 有人能解释为什么我在请求中的数组没有与类A中的数组映射吗?

  • 我有一个JSON对象,如下所示: