如何使用Retrofit和GSON解析由[]包围的JSON对象列表? [英] How to parse list of JSON objects surrounded by [] using Retrofit and GSON?

查看:174
本文介绍了如何使用Retrofit和GSON解析由[]包围的JSON对象列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  http://< server_address>:3000 / sizes 

该URL返回一个包含 json数组的非常简单的响应,如下所示: p>

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

现在,我试图使用Retrofit 2来使用此响应使用GSON 。



我添加了一个模型:

  @ lombok.AllArgsConstructor 
@ lombok.EqualsAndHashCode
@ lombok.ToString
public class Size {
private int id;
私人字符串名称;
私有布尔激活;

@SerializedName(created_at)
private String createdAt;

@SerializedName(updated_at)
private String updatedAt;
}

和服务:

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

我已经实例化了一个Retrofit:

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

以及我的服务:

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

现在,尝试调用数据:

< pre $ 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());


$ b $覆盖
public void onFailure(调用< List< Size>> call,Throwable t){
System.out.println (t.getMessage());
}
});

结果是一个例外:


java.lang.IllegalStateException 期望的BEGIN_OBJECT,但STRING 在第1行第18列路径$ [0] .name


我想这个错误是由于这个原因造成的, REST API返回的是一个数组或对象的响应。 >


  1. 我是否正确?

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

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

另外,使用纯GSON对上述json进行反序列化也可以这样做:

  Type typesType = new TypeToken< List&Size>>(){}。getType(); 
列表<大小> size = new Gson()。fromJson(json,sizesType);

但我不知道如何让Retrofit 2使用它。



在此先感谢。

解决方案

有趣的事实是...我的代码非常好。至少是上面提到的问题。



我从 Size 模型中删除了一行。

当我关注代码本身(特别是Retrofit的配置)时,我完全忽略了导入。



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




  • name
  • createdAt

  • updatedAt



IntelliJ IDEA的代码完成暗示了我




  • 不是 java.lang .String

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



完全搞砸了 Gson 的反序列化



谈到奖励...



我决定将自己的答案标记为有效。为什么? 为了确保这些开发人员与我一样遇到同样的麻烦,确保您有有效的导入


非常感谢上面提到的优秀服务。



由于我只有一个赏金,我决定奖励 xiaoyaoworm 因为他的代码更符合我的需求(我没有把它写在我的问题中,但编写这样简单的服务的想法 - 就像我在我的问题中提出的 - 是为了隐藏最终用户实现细节并且不使用 JsonArray ,并且在 BNK 响应中)。



更新1:



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

对于上述情况, 确切两个字段需要大小模型需要注释 - created_at updated_at



我甚至测试过几个版本的 converter-gson 库(我看到了 xiaoyaoworm 除了我之外都用过) - 它没有改变任何东西。注释是必要的。



否则 - 再次,非常感谢!


I've created a simple REST endpoint:

http://<server_address>:3000/sizes

This URL returns a very simple response containing a json array as follows:

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

Now, I'm trying to consume this response using Retrofit 2 with GSON.

I've added a model:

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

And service:

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

I've instantiated a Retrofit:

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

And my service:

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

Now, trying to call the data:

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());
    }
});

What ends up with an exception:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 18 path $[0].name

I suppose the error is caused by that, the REST API returns a response which is an array nor object.

  1. Am I correct?
  2. What is the easiest way to make this code to work?

REST service cannot be modified, so the response must stay as is.

Also, deserialization of the above json using pure GSON might be done by:

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

But I have no idea how to make Retrofit 2 to use this.

Thanks in advance.

解决方案

The funny fact is... My code is perfectly fine. At least the one presented in the question above.

I've ended up removing one line from my Size model.

As I focused on the code itself (especially Retrofit's configuration) I've totally ignored imports.

It turned out - while implementing Size model when I've started typing String class for model's fields:

  • name
  • createdAt
  • updatedAt

IntelliJ IDEA's code completion suggested me

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

what totally messed up Gson's deserialization.

When it comes to rewards...

I've decided to mark as valid my own answer. Why?

  • To ensure that, every of those developers, who will come with exactly same trouble as me - make sure you have valid imports.

Many thanks goes to gentlmen above for their great services.

As I have only one bounty I've decided reward xiaoyaoworm as his code better match my needs (I haven't written it in my question but the idea of writing such simple service - as I've presented in my question - is to hide from the end-user implementation details and not use JsonArray and such like in BNK response).

Update 1:

The only problem with xiaoyaoworm's answer is that, he suggested the Size model do not need any annotations what is totally wrong for the quoted JSON example.

For above case, exact two fields of the Size model needs annotations - created_at and updated_at.

I've even tested few versions of the converter-gson library (I saw xiaoyaoworm have used other than me) - it hasn't changed anything. Annotations were necessary.

Otherwise - again, many thanks!

这篇关于如何使用Retrofit和GSON解析由[]包围的JSON对象列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆