当前位置: 首页 > 面试题库 >

如何使用Retrofit和GSON解析[]包围的JSON对象列表?

晏修诚
2023-03-14
问题内容

我创建了一个简单的REST端点:

http://<server_address>:3000/sizes

此URL返回一个非常简单的响应,其中包含 json数组 ,如下所示:

[
  { "id": 1, "name": "Small", "active": true },
  { "id": 2, "name": "Medium", "active": true },
  { "id": 3, "name": "Large", "active": true }
]

现在,我尝试 使用带有GSON的Retrofit 2使用此响应

添加了一个模型:

@lombok.AllArgsConstructor
@lombok.EqualsAndHashCode
@lombok.ToString
public class Size {
    private int id;
    private String name;
    private boolean active;

    @SerializedName("created_at")
    private String createdAt;

    @SerializedName("updated_at")
    private String updatedAt;
}

和服务:

public interface Service {
    @GET("sizes")
    Call<List<Size>> loadSizes();
}

我实例化了一个改造:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://<server_address>:3000")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

而我的服务:

Service service = retrofit.create(Service.class);

现在,尝试调用数据:

service.loadSizes().enqueue(new Callback<List<Size>>() {
    @Override
    public void onResponse(Call<List<Size>> call, Response<List<Size>> response) {
        for(Size size: response.body()) {
            System.out.println(size.toString());
        }
    }

    @Override
    public void onFailure(Call<List<Size>> call, Throwable t) {
        System.out.println(t.getMessage());
    }
});

最终导致异常:

java.lang.IllegalStateException预期为BEGIN_OBJECT,但 位于第1行第18列的路径$
[0] .name

我想该错误是由以下原因引起的, REST API返回的响应既不是数组也不是object

  1. 我对么?
  2. 使此代码正常工作的最简单方法是什么?

REST服务无法修改 ,因此响应必须保持原样。

另外,可以通过以下方式使用纯GSON对上述json进行反序列化:

Type sizesType = new TypeToken<List<Size>>(){}.getType();
List<Size> size = new Gson().fromJson(json, sizesType);

但是我不知道如何使Retrofit 2能够使用它。

提前致谢。


问题答案:

有趣的事实是…我的代码完全正确。至少是以上问题中提出的一个。

我最终从Size模型中删除了一条线。

当我专注于代码本身(尤其是Retrofit的配置)时,我完全忽略了导入。

事实证明-在实现Size模型时,我开始String为模型的字段输入类:

  • name
  • createdAt
  • updatedAt

IntelliJ IDEA的 代码完成提示我

  • java.lang.String
  • com.sun.org.apache.xpath.internal.operations.String

彻底搞乱了Gson反序列化

当谈到奖励…

我决定将自己的答案标记为有效。为什么?

  • 为确保这一点,与我完全一样遇到麻烦的所有开发人员-请 确保您具有有效的导入

非常感谢上面的绅士们的出色服务。

由于我只有一个赏金,因此我决定奖励xiaoyaoworm,因为他的代码可以更好地满足我的需求(我没有在问题中编写它,但是编写这样简单的服务(如我在问题中所介绍的)的想法是隐藏从最终用户的实施细节,而不是JsonArray在BNK响应中使用等)。

更新1:

xiaoyaoworm答案的唯一问题是,他建议该Size模型
不需要任何注释, 这对于引用的JSON示例是完全错误的。

对于上述情况, 确切的两个字段 中的Size模型 需要注解 - created_atupdated_at

我什至已经测试了该converter- gson库的几个版本(我看到xiaoyaoworm]除了我以外)还使用过)-它没有改变任何东西。注释是必要的。

否则-再次感谢!



 类似资料:
  • 我创建了一个简单的RESTendpoint: 我实例化了一个改型: 我的服务: 现在,尝试调用数据: null 但我不知道如何使改型2使用这个。 提前谢了。

  • 问题内容: 我有一个像这样的JSON对象: 并尝试与Gson解析: 但是“ responceBean”始终为“ null” 这是所有其他类: 这是我的最新尝试。我不知何故找不到正确的方法。任何帮助将不胜感激。 问题答案: 您的 JSON模型与您的对象模型不匹配 。 您需要一个中间层来填补空白: TypeAdapter 。 而且,没有用户的命名信息。 最后是名称不匹配:JSON中的“ worklog

  • 我需要使用Gson将传入的json消息解析为Java对象。类“MessageBody”应该用于向Gson提供信息。fromJson(json,MessageBody.class); json消息如下所示。 第一层有三个静态字段。第三个字段(“字段”)是“数据字段”对象的列表。 DataField对象有一个类型字段和一个值字段。它的价值可以是异质的。预期类型为:“字符串”、“int”、“布尔”和“H

  • 问题内容: 这是我对Web服务的JSONArray响应: 这是ApiInterface.java 这是方法和响应的调用: 到目前为止,它失败了,这里是logcat输出: 它无法执行响应。指导我分析此响应。 问题答案: 请尝试使用这个 如果您遇到任何问题,请告诉我。

  • 问题内容: 我们的团队决定使用Retrofit 2.0, 并且我正在对该库进行一些初步研究。如标题中所述,我想通过Android应用中的Retrofit 2.0解析一些嵌套的JSON对象。 例如,这是一个嵌套的JSON对象,其格式为: 我对数组内的JSON对象感兴趣。我注意到有一些关于通过Retrofit 1.X解析嵌套JSON对象的文章,但是最新的Retrofit 2.0API发生了很大变化,这

  • 我有一个这样的JSON文件: 如何使用Gson仅解析“数据”部分?我的想法是将JSON读入地图,然后用我在GSON中的键“数据”解析普通JSON内容。我能做些更优雅的事吗?