如何使用改造将对象解析为json

时间:2017-12-26 13:47:32

标签: java android gson retrofit2

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

预计BEGIN_ARRAY但是BEGIN_OBJECT

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

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

响应api

  {
    "_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);

            }
        });

4 个答案:

答案 0 :(得分:1)

你是在正确的道路上,但响应是整个json而不仅仅是你想要的数据部分。

我会创建ResponseApi类:

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

更改ApiInterface:

Call<ArrayList<ServiceData>> getData(); 

要:

Call<ResponseApi> getData(); 

同样在您的活动中,将所有 ArrayList&lt; ServiceData&gt; 替换为 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中使用重构)此服务 var(在服务类中):

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

servicesList

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

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

无论是否重命名它都会起作用,但在我看来,代码更具可读性。

答案 1 :(得分:0)

试试这个

您的解析映射存在问题,请尝试以下模型

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

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

    }

答案 2 :(得分:0)

尝试从每个位置删除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);

            }
        });

答案 3 :(得分:0)

您呼叫并等待List。 Call<ArrayList<ServiceData>>
但在回复中,你有一个对象。

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

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

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

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