【问题标题】:How to make parse object to json using retrofit [duplicate]如何使用改造将对象解析为 json [重复]
【发布时间】:2017-12-26 13:47:31
【问题描述】:

下一个问题是,当尝试使用网络服务时,然后是消息和演示;

应为 BEGIN_ARRAY,但为 BEGIN_OBJECT

我不确定如何制作场景,我已经从 web 服务中获取了数据,但是当它不是一个简单的数组时。

我尝试了很多替代方法,但都没有成功。

响应接口

  {
    "_links": {
        "self": {
            "href": "http://url.com/service?page=1"
        },
        "first": {
            "href": "http://url.com/service"
        },
        "last": {
            "href": "http://url.com/service?page=1"
        }
    },
    "_embedded": {
        "data": [
            {
                "id": 1,
                "nome": "teste",
                "_links": {
                    "self": {
                        "href": "http://url.com/service/1"
                    }
                }
            },
            {
                "id": 2,
                "nome": "teste 2",
                "_links": {
                    "self": {
                        "href": "http://url.com/service/2"
                    }
                }
            }
        ]
    },
    "page_count": 1,
    "page_size": 25,
    "total_items": 2,
    "page": 1
}

客户

public class ApiClient {

    private static final String BASE_URL = "http://url.com/";


    private static Retrofit getClient() {

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

        Gson gson = new GsonBuilder().setLenient().create();

        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();
    }

    /**
     * Get API Service
     *
     * @return API Service
     */
    public static ApiInterface getApiService() {
        return getClient().create(ApiInterface.class);
    }

}

界面

/**
 * Class ApiInterface
 */
public interface ApiInterface
{

    @Headers("Accept: application/json")
    @GET("/service")
    Call<ArrayList<ServiceData>> getData();


}

服务

public class Service{

    @SerializedName("data")
    private ArrayList<ServiceData> service = new ArrayList<>();

}

服务数据

public class ServiceData {
    @SerializedName("id")
    private int id;


    public ServiceData(int id, String nome) {
        this.id = id;

    }

    public int getId() {
        return id;
    }

}

活动

 final Call<ArrayList<ServiceData>> service = apiService.getService();
        service.enqueue(new Callback<ArrayList<ServiceData>>() {
            @Override
            public void onResponse(Call<ArrayList<ServiceData>> call, Response<ArrayList<ServiceData>> response) {
                Log.e(TAG, "" + response.body());
            }

            @Override
            public void onFailure(Call<ArrayList<ServiceData>> call, Throwable t) {
                Log.e(TAG, "" + t);

            }
        });

【问题讨论】:

  • 您的响应是整个 JSON,而您创建的模型仅适用于“_embedded.data”字段

标签: java android gson retrofit2


【解决方案1】:

您走在正确的道路上,但响应是整个 json,而不仅仅是您想要的 data 部分。

我会创建 ResponseApi 类:

public class ResponseApi {
    @SerializedName("_embedded")
    private Service embedded;
}

并在 ApiInterface 上进行更改:

Call<ArrayList<ServiceData>> getData(); 

收件人:

Call<ResponseApi> getData(); 

同样在您的活动中,将所有 ArrayList 替换为 ResponseApi

只需进行这些更改,您的代码就可以正常工作。然后你需要在 ResponseApi 和 Service 中添加 getter 来访问保存的数据。


更新添加一些 getter:

我们需要获取服务的ServiceData的ArrayList的可能性:

public class Service {
    // Your current code

    public List<ServiceData> getServices() {
        return service;
    }
}

我们还可以在 ResponseApi 中创建一个 getter 来嵌入 getEmbedded(我将仅将代码添加为信息),但由于我们只想要服务,因此我们可以创建一个 getter 到服务 getEmbededServices 并使用最后一种方法。

public class ResponseApi {
    // Your current code

    public Service getEmbedded() { // Not used, only shown as info
        return embedded;
    }

    public List<ServiceData> getEmbeddedServices() {
        return embedded.getServices();
    }
}

这样,当您在 onResponse 方法中收到一个 ResponseApi 对象时,您可以调用它的 getEmbeddedServices 来获取 ServiceData 列表,然后您可以遍历它们来获取 id:

@Override
public void onResponse(Call<ResponseApi> call, Response<ResponseApi> response) {
    Log.d(TAG, "services: " + response.getEmbeddedServices());
    // Here you can loop the response.getEmbeddedServices() which is a List of ServiceData and get each of the ids. Ex:
    for (ServiceData serviceData : response.getEmbeddedServices()) {
        Log.d(TAG, "service Id: " + serviceData.getId());
        // Here you have access to the ids and can do whatever you need with them.
    }
}

顺便说一下,仅作为建议,我将重命名(在 Android Studio 中重构)这个 service var(在 Service 类中):

private ArrayList<ServiceData> service = new ArrayList<>();

服务列表

private ArrayList<ServiceData> servicesList = new ArrayList<>();

也许还可以将 Service 类重构为 ServicesList 类。

无论您是否重命名它们都可以工作,但在我看来,这样的代码更具可读性。

【讨论】:

  • 你的回答很人性化,很完美,谢谢,我得到了我的数组,一个问题,在这种情况下我的回答数据将不再被使用?如果我只想获取 id,那怎么可能呢?我已经尝试以某种方式使用该服务创建我的属性并创建 getter,但我无法访问它们。
  • 谢谢,别担心,我刚刚添加了一个更新来解释通过添加一些 getter 来访问所需数据的方法。我没有运行它,但它应该可以工作。
  • 稍作修改就得到了预期的结果,我无话可说。
【解决方案2】:

试试这个

您的 Parsing 映射有问题,请在 Model 下尝试

ServiceData.java

public class ServiceData {

@SerializedName("_links")
@Expose
private Links links;
@SerializedName("_embedded")
@Expose
private Embedded embedded;
@SerializedName("page_count")
@Expose
private Integer pageCount;
@SerializedName("page_size")
@Expose
private Integer pageSize;
@SerializedName("total_items")
@Expose
private Integer totalItems;
@SerializedName("page")
@Expose
private Integer page;

public Links getLinks() {
return links;
}

public void setLinks(Links links) {
this.links = links;
}

public Embedded getEmbedded() {
return embedded;
}

public void setEmbedded(Embedded embedded) {
this.embedded = embedded;
}

public Integer getPageCount() {
return pageCount;
}

public void setPageCount(Integer pageCount) {
this.pageCount = pageCount;
}

public Integer getPageSize() {
return pageSize;
}

public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}

public Integer getTotalItems() {
return totalItems;
}

public void setTotalItems(Integer totalItems) {
this.totalItems = totalItems;
}

public Integer getPage() {
return page;
}

public void setPage(Integer page) {
this.page = page;
}

}

self_.java

    public class Self_ {

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

    public String getHref() {
    return href;
    }

    public void setHref(String href) {
    this.href = href;
    }

    }

Self.java

    public class Self {

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

    public String getHref() {
    return href;
    }

    public void setHref(String href) {
    this.href = href;
    }

    }

Links_.java

    public class Links_ {

    @SerializedName("self")
    @Expose
    private Self_ self;

    public Self_ getSelf() {
    return self;
    }

    public void setSelf(Self_ self) {
    this.self = self;
    }

    }

Links.java

    public class Links {

    @SerializedName("self")
    @Expose
    private Self self;
    @SerializedName("first")
    @Expose
    private First first;
    @SerializedName("last")
    @Expose
    private Last last;

    public Self getSelf() {
    return self;
    }

    public void setSelf(Self self) {
    this.self = self;
    }

    public First getFirst() {
    return first;
    }

    public void setFirst(First first) {
    this.first = first;
    }

    public Last getLast() {
    return last;
    }

    public void setLast(Last last) {
    this.last = last;
    }
    }

最后一个.java

    public class Last {

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

    public String getHref() {
    return href;
    }

    public void setHref(String href) {
    this.href = href;
    }

    }

First.java

    public class First {

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

    public String getHref() {
    return href;
    }

    public void setHref(String href) {
    this.href = href;
    }

    }

Embedded.java

    public class Embedded {

    @SerializedName("data")
    @Expose
    private List<Datum> data = null;

    public List<Datum> getData() {
    return data;
    }

    public void setData(List<Datum> data) {
    this.data = data;
    }

    }

Datum.java

    public class Datum {

    @SerializedName("id")
    @Expose
    private Integer id;
    @SerializedName("nome")
    @Expose
    private String nome;
    @SerializedName("_links")
    @Expose
    private Links_ links;

    public Integer getId() {
    return id;
    }

    public void setId(Integer id) {
    this.id = id;
    }

    public String getNome() {
    return nome;
    }

    public void setNome(String nome) {
    this.nome = nome;
    }

    public Links_ getLinks() {
    return links;
    }

    public void setLinks(Links_ links) {
    this.links = links;
    }

    }

【讨论】:

    【解决方案3】:

    尝试从每个地方删除ArrayList并直接使用ServiceData

    界面

    /**
     * Class ApiInterface
     */
    public interface ApiInterface
    {
    
        @Headers("Accept: application/json")
        @GET("/service")
        Call<ServiceData> getData();
    
    
    }
    

    服务数据

    public class ServiceData {
        @SerializedName("id")
        private int id;
    
    
        public ServiceData(int id, String nome) {
            this.id = id;
    
        }
    
        public int getId() {
            return id;
        }
    
    }
    

    活动

     final Call<ServiceData> service = apiService.getService();
            service.enqueue(new Callback<ServiceData>() {
                @Override
                public void onResponse(Call<ServiceData> call, Response<ServiceData> response) {
                    Log.e(TAG, "" + response.body());
                }
    
                @Override
                public void onFailure(Call<ServiceData> call, Throwable t) {
                    Log.e(TAG, "" + t);
    
                }
            });
    

    【讨论】:

      【解决方案4】:

      您打电话并等待列表。 Call&lt;ArrayList&lt;ServiceData&gt;&gt;
      但是在响应中,您有一个对象。

      [...] - 是数组(列表)
      {...} - 是对象

      您需要为所有参数正确创建类。

      试试看这个服务(或类似的):
      http://www.jsonschema2pojo.org/

      或者Android Studio(IDEA)也有一个插件(GsonFormat)用于转换JSON。

      【讨论】:

        猜你喜欢
        • 2020-01-29
        • 2018-05-10
        • 1970-01-01
        • 2020-02-29
        • 2016-02-13
        • 2017-05-12
        • 1970-01-01
        • 1970-01-01
        • 2016-06-20
        相关资源
        最近更新 更多