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

改装呼叫具有相同的名称不同的数据类型

钮巴英
2023-03-14

API调用

@GET("users/{user_id}/grid")
    Call<ArrayList<Grid>> getGrid(@Path("user_id") Integer id, @Header("Authorization") String authHeader);

Grid.class
public class Grid {

        @SerializedName("category")
        @Expose
        private String category;

        @SerializedName("type")
        @Expose
        private String type;

        @SerializedName("title")
        @Expose
        private String title;

        @SerializedName("equation_list")
        @Expose
        private List<Integer> equationList = null;  // This is the issue
}

API响应equation_list字段包含整数数组或字符串。例如:

"equation_list": "7", or 
"equation_list": [7],

但我有个例外

com.google.gson.java.lang.IllegalStateException:预期BEGIN_ARRAY但在第1行第1586列路径$[5]处是STRING。equation_list

我如何满足我的要求?

共有1个答案

麹承
2023-03-14

我认为可以创建一个类型来处理String和ArrayList这两种数据类型。然后,您可以为GSON实现一个定制的JsonAdapter来处理这种类型的定制反序列化。

让我们创建派生自java的等式列表。util。阵列列表

/**
 * Custom type to handle both String and ArrayList<Integer> types
 *
 * @author Yavuz Tas
 *
 */
public class EquationList extends ArrayList<Integer> {

}

在我们为等式列表类型实现JsonAdapter之后

/**
 * Custom JsonAdapter for GSON to handle {@link EquationList} converstion
 * 
 * @author Yavuz Tas
 *
 */
public class EquationListJsonAdapter extends TypeAdapter<EquationList> {

    @Override
    public void write(JsonWriter out, EquationList user) throws IOException {

        // Since we do not serialize EquationList by gson we can omit this part.
        // If you need you can check
        // com.google.gson.internal.bind.ObjectTypeAdapter class
        // read method for a basic object serialize implementation

    }

    @Override
    public EquationList read(JsonReader in) throws IOException {

        EquationList deserializedObject = new EquationList();

        // type of next token
        JsonToken peek = in.peek();

        // if the json field is string
        if (JsonToken.STRING.equals(peek)) {
            String stringValue = in.nextString();
            // convert string to integer and add to list as a value
            deserializedObject.add(Integer.valueOf(stringValue));
        }

        // if it is array then implement normal array deserialization
        if (JsonToken.BEGIN_ARRAY.equals(peek)) {
            in.beginArray();

            while (in.hasNext()) {
                String element = in.nextString();
                deserializedObject.add(Integer.valueOf(element));
            }

            in.endArray();
        }

        return deserializedObject;
    }
}

最后,我们将适配器注册到Grid中的equationList字段

public class Grid {

    @SerializedName("category")
    @Expose
    private String category;

    @SerializedName("type")
    @Expose
    private String type;

    @SerializedName("title")
    @Expose
    private String title;

    @JsonAdapter(value = EquationListJsonAdapter.class)
    @SerializedName("equation_list")
    @Expose
    private EquationList equationList;

}

这将正确处理您的回答,如下所示

"equation_list": "7", or "equation_list": [7]

请注意,任何字符串响应都会自动转换为整数,并作为列表元素添加到等式列表中。您可以通过在EquationListJsonAdapter的read方法中更改实现来更改此行为。

我希望这有帮助。干杯!

 类似资料:
  • 问题内容: 以下代码可以正常工作。在两个不同的结构上操作并打印该结构的字段的两种方法: 在控制台中显示所需的输出: 现在 ,如果我以以下方式更改方法签名,则会出现编译错误。我只是将方法的接收者移动到方法的参数: 我什至无法编译程序: 问 :为什么 当 方法具有相同的名称和Arity 时 ,我可以在接收器中互换结构类型,而不能在参数中互换结构类型? 问题答案: 因为Go不支持在其参数类型上重载用户定

  • 问题内容: 我目前正在使用Gson用Java编写RSS feed解析器。我正在将RSS的XML转换为JSON,然后使用Gson将JSON反序列化为Java POJO(有点回旋,但是有原因)。就下面列出的Feed#1( BBC )进行反序列化而言,一切工作正常,但是对于下面列出的Feed#2( NPR ),我开始抛出异常。 我认为我已经确定了问题,但不确定如何解决该问题: 这是由于以下两个RSS F

  • 问题内容: 我在这里已经读到,在Java中,具有相同名称但不同类型的两个变量可以在同一范围内共存。我的意思是这个 但是所有的Java IDE都不允许这样的代码。我想知道这样的代码在语法上是否正确,或者只是IDE不允许这样的代码防止歧义。 无论如何,这是网站的摘录 “如果幸运的话,您也许能够重新编译Jad的输出。 但是,Java VM对于变量命名的规则比Java语言本身更为宽松。例如,一个有效的类文

  • 但所有java IDE都不允许这样的代码。我想知道这样的代码在语法上是否真的正确,或者只是IDE不允许这样的代码来防止歧义。 总之,这里是从网站上摘录的 “如果你幸运的话,你也许可以重新编译JAD的输出。然而,Java VM对变量命名的规则比Java语言本身更宽松。例如,一个有效的类文件可以有几个名为'a'的变量,只要它们有不同的类型。如果你反编译这样的类,你得到的源代码将是无效的。 JAD通常会

  • 问题内容: 我今天在另一个问题中提出了这个问题,但是 由于措辞的方式,恐怕无法解决任何问题。 我有一个json输入,其中包含以下数据: 杰森 如您所见,option_value项是一个对象中的Array和 另一个对象中的简单字符串。 我怎样才能让Gson正确处理呢?我的类将此描述为 List对象,因此它适用于option_value是 数组的前几个项目,但是当它成为字符串时,应用程序崩溃,并且我收

  • 我正在使用的数据库有许多具有相同列但(显然)具有不同表名的表(不是我设计的)。例如(这些是数据库表名): 有没有可能用JPA和Hibernate将这些映射到一个Java类实体?类的名称是,然后在使用它时传入例如,以便对象使用表? 还是只使用普通的、普通的Java对象来完成这样的任务更好? 谢谢你!