繁体   English   中英

在android中使用retrofit 2解析具有多个对象的Json数组

[英]Parse Json array with multiple objects using retrofit 2 in android

我正在我的项目中使用改进2的网络功能,我能够解析服务器的json对象响应,但现在我应该解析一个看起来像这样的json数组

[
    {
        "id_asset": 1,
        "id_category": 1,
        "id_brand": 2,
        "name": "Samsung Galaxy 6",
        "status": 1,
        "updated_at": "Oct 3, 2016 10:24:28 AM",
        "rank": 1,
        "rate": {
            "id_asset_rate": 2,
            "id_asset": 1,
            "value": 5000,
            "loan_to_value": 50,
            "offered": 2500,
            "annual_rate": 3,
            "quantity": 5,
            "created_at": "Oct 23, 2016 5:31:31 AM",
            "updated_at": "Oct 23, 2016 5:32:31 AM"
        },
        "best_rate": {
            "id_asset": "1",
            "value": "5000",
            "loan_to_value": "50",
            "offered": "2500",
            "annual_rate": "3",
            "quantity": "5",
            "rank": "1"
        },
        "category": {
            "id_category": 1,
            "id_parent": 0,
            "name": "Mobile Phones",
            "image": "",
            "sort": 1,
            "status": 1,
            "created_at": null,
            "updated_at": null,
            "_links": {
                "self": {
                    "href": "/v1/categories/1"
                }
            }
        },
        "brand": {
            "id_brand": 2,
            "name": "Samsung",
            "status": 1,
            "created_at": null,
            "updated_at": null
        },
        "_links": {
            "self": {
                "href": "/v1/assets/1"
            }
        }
    },
    {
        "id_asset": 2,
        "id_category": 1,
        "id_brand": 1,
        "name": "i Phone 5",
        "status": 1,
        "updated_at": "Oct 3, 2016 8:04:36 AM",
        "rank": false,
        "rate": null,
        "best_rate": false,
        "category": {
            "id_category": 1,
            "id_parent": 0,
            "name": "Mobile Phones",
            "image": "",
            "sort": 1,
            "status": 1,
            "created_at": null,
            "updated_at": null,
            "_links": {
                "self": {
                    "href": "/v1/categories/1"
                }
            }
        },
        "brand": {
            "id_brand": 1,
            "name": "Apple",
            "status": 1,
            "created_at": null,
            "updated_at": null
        },
        "_links": {
            "self": {
                "href": "/v1/assets/2"
            }
        }
    }
]

这是服务器的响应,我为响应创建了这个POJO

public class AssetResponse {
    private Integer id_asset;
    private Integer id_category;
    private Integer id_brand;
    private String  name;
    private Integer status;
    private String updated_at;

    private AssetRate assetRate;
    private AssetCategory assetCategory;
    private Links links;
    private Self self;
    private AssetBrand assetBrand;
    private HasLinked hasLinked;


    public Integer getId_asset() {
        return id_asset;
    }

    public void setId_asset(Integer id_asset) {
        this.id_asset = id_asset;
    }

    public Integer getId_category() {
        return id_category;
    }

    public void setId_category(Integer id_category) {
        this.id_category = id_category;
    }

    public Integer getId_brand() {
        return id_brand;
    }

    public void setId_brand(Integer id_brand) {
        this.id_brand = id_brand;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(String updated_at) {
        this.updated_at = updated_at;
    }

    public AssetRate getAssetRate() {
        return assetRate;
    }

    public void setAssetRate(AssetRate assetRate) {
        this.assetRate = assetRate;
    }

    public AssetCategory getAssetCategory() {
        return assetCategory;
    }

    public void setAssetCategory(AssetCategory assetCategory) {
        this.assetCategory = assetCategory;
    }

    public Links getLinks() {
        return links;
    }

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

    public Self getSelf() {
        return self;
    }

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

    public AssetBrand getAssetBrand() {
        return assetBrand;
    }

    public void setAssetBrand(AssetBrand assetBrand) {
        this.assetBrand = assetBrand;
    }

    public HasLinked getHasLinked() {
        return hasLinked;
    }

    public void setHasLinked(HasLinked hasLinked) {
        this.hasLinked = hasLinked;
    }

    private class AssetRate {

        private Integer id_asset_rate;
        private Integer id_asset;
        private Double value;
        private Double loan_to_value;
        private Double offered;
        private Double annual_rate;
        private String updated_at;

        public Integer getId_asset_rate() {
            return id_asset_rate;
        }

        public void setId_asset_rate(Integer id_asset_rate) {
            this.id_asset_rate = id_asset_rate;
        }

        public Integer getId_asset() {
            return id_asset;
        }

        public void setId_asset(Integer id_asset) {
            this.id_asset = id_asset;
        }

        public Double getValue() {
            return value;
        }

        public void setValue(Double value) {
            this.value = value;
        }

        public Double getLoan_to_value() {
            return loan_to_value;
        }

        public void setLoan_to_value(Double loan_to_value) {
            this.loan_to_value = loan_to_value;
        }

        public Double getOffered() {
            return offered;
        }

        public void setOffered(Double offered) {
            this.offered = offered;
        }

        public Double getAnnual_rate() {
            return annual_rate;
        }

        public void setAnnual_rate(Double annual_rate) {
            this.annual_rate = annual_rate;
        }

        public String getUpdated_at() {
            return updated_at;
        }

        public void setUpdated_at(String updated_at) {
            this.updated_at = updated_at;
        }
    }

    private class AssetCategory {

        private Integer id_category;
        private Integer id_parent;
        private String name;
        private String image;
        private Integer sort;
        private Integer status;
        private String created_at;
        private String updated_at;

        private Links links;


        public Integer getId_category() {
            return id_category;
        }

        public void setId_category(Integer id_category) {
            this.id_category = id_category;
        }

        public Integer getId_parent() {
            return id_parent;
        }

        public void setId_parent(Integer id_parent) {
            this.id_parent = id_parent;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getImage() {
            return image;
        }

        public void setImage(String image) {
            this.image = image;
        }

        public Integer getSort() {
            return sort;
        }

        public void setSort(Integer sort) {
            this.sort = sort;
        }

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }

        public String getCreated_at() {
            return created_at;
        }

        public void setCreated_at(String created_at) {
            this.created_at = created_at;
        }

        public String getUpdated_at() {
            return updated_at;
        }

        public void setUpdated_at(String updated_at) {
            this.updated_at = updated_at;
        }

        public Links getLinks() {
            return links;
        }

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

    private class Links {
        @SerializedName("self")
        @Expose
        private Self self;

        /**
         *
         * @return
         * The self
         */
        public Self getSelf() {
            return self;
        }

        /**
         *
         * @param self
         * The self
         */
        public void setSelf(Self self) {
            this.self = self;
        }
    }

    private class Self {
        @SerializedName("href")
        @Expose
        private String href;

        /**
         *
         * @return
         * The href
         */
        public String getHref() {
            return href;
        }

        /**
         *
         * @param href
         * The href
         */
        public void setHref(String href) {
            this.href = href;
        }


    }

    private class AssetBrand {


        private Integer id_brand;
        private String name;
        private Integer status;
        private String created_at;
        private String updated_at;

        public Integer getId_brand() {
            return id_brand;
        }

        public void setId_brand(Integer id_brand) {
            this.id_brand = id_brand;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }

        public String getCreated_at() {
            return created_at;
        }

        public void setCreated_at(String created_at) {
            this.created_at = created_at;
        }

        public String getUpdated_at() {
            return updated_at;
        }

        public void setUpdated_at(String updated_at) {
            this.updated_at = updated_at;
        }


    }

    private class HasLinked {

        private Integer has_linked;

        private Links links;

        public Integer getHas_linked() {
            return has_linked;
        }

        public void setHas_linked(Integer has_linked) {
            this.has_linked = has_linked;
        }

        public Links getLinks() {
            return links;
        }

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

    }
   }
}

我的pojo是对的吗? 我的问题是,我无法解析这个回复。 任何帮助将不胜感激。 提前致谢

编辑:这是我对服务器的请求(使用rest api)

@GET("url")
Call<AssetResponse> getAssetList();

编辑2:我已经将代码更改为List,正如Niko Adrianus Yuwono所建议的那样。

这是新的变化

    private void getAssets() {

        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.addInterceptor(logging);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(httpClient.build())
                .build();

        final ApiInterface apiInterface = retrofit.create(ApiInterface.class);

        final AssetRequest assetRequest = new AssetRequest();
        assetRequest.setAcc_tok(ACCESS_TOKEN);

        final Call<List<AssetResponse>> assetList = apiInterface.getAssetList();

        assetList.enqueue(new Callback <List<AssetResponse>>() {

            @Override
            public void onResponse(Call<List<AssetResponse>> call, Response<List<AssetResponse>> response) {
                int statusCode = response.code();

                List<AssetResponse> assetResponseList = response.body();

                if (statusCode == 200) {

                  for (int i = 0; i < assetResponseList.size(); i++ ){
                        Integer id_asset = assetResponseList.get(i).getId_asset();
                        Integer id_category = assetResponseList.get(i).getId_category();
                        Integer status = assetResponseList.get(i).getStatus();
                        String name = assetResponseList.get(i).getName();
                        Log.d("Assets ","Asset id_asset  bb : " + id_asset);
                        Log.d("Assets ","Asset id_category  bb : " + id_category);
                        Log.d("Assets ","Asset name  bb : " + name);
                        Log.d("Assets ","Asset status  bb : " + status);

                        Double val = assetResponseList.get(i).getAssetRate().getValue();
                        Log.d("val ","val is : " +val);

                    }
                } else {
                    Toast.makeText(getContext(), "network error " + statusCode, Toast.LENGTH_LONG).show();

   }
  }

@Override
public void onFailure(Call<List<AssetResponse>> call, Throwable t) {

       Log.d("Asset GET Failure", "onFailure: " + t.getMessage());
      //showProgress(false);
    }
 });
}

这是来自服务器的响应

D /资产:资产id_asset bb:1 D /资产:资产id_category bb:1 D /资产:资产名称bb:三星Galaxy 6 D /资产:资产状况bb:1 10-26 13:13:17.898 22784-22784 / D / AndroidRuntime:关闭VM 10-26 13:13:17.898 22784-22784 / E / AndroidRuntime:FATAL EXCEPTION:main进程:,PID:22784 java.lang.NullPointerException:尝试调用虚方法'java.lang.Double空对象引用上的.api.model.AssetResponse $ AssetRate.getValue()'
.AssetDatabaseFragment $ 2.onResponse(AssetDatabaseFragment.java:133)
retrofit2.ExecutorCallAdapterFactory $ ExecutorCallbackCall $ 1 $ 1.run(ExecutorCallAdapterFactory.java:68)android.os.Handler.handleCallback(Handler.java:739)
android.os.Handler.dispatchMessage(Handler.java:95)
android.os.Looper.loop(Looper.java:148)
android.app.ActivityThread.main(ActivityThread.java:5417)
java.lang.reflect.Method.invoke(Native方法)
com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:726)com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

每当我访问内部对象时,它会像上面那样抛出错误

您的POJO看起来正确,但您的JSON响应是JSONArray,因此您需要将其声明为对象列表而不是对象

@GET("url")
Call<List<AssetResponse>> getAssetList();

并且您需要将内部类访问权限更改为public,以便GSON可以查看该类的setter和getter。

您的Json键值数据正在从一个索引更改为另一个索引。

错了Json:

[{
//Make this either integer or boolean
 "rank": 1,
// best rate is object here in the next index, it's treated as boolean. 
  "best_rate": {
            "id_asset": "1",
            "value": "5000",
            "loan_to_value": "50",
            "offered": "2500",
            "annual_rate": "3",
            "quantity": "5",
            "rank": "1"
        }

},
{
"rank":false,
"best_rate":false,
}
]

我和你的json在github上共享了一个完整的项目。 https://github.com/lingarajsankaravelu/retrofit2v.git

改进代码应该像我在问题评论中提到的那样。

@GET("url")
Call<List<AssetResponse>> getAssetList();

正如您要求解释您的pojo类中的更改,它应该是这样的。

AssetReponse.class:

public class AssetResponse {
    private Integer id_asset;
    private Integer id_category;
    private Integer id_brand;
    private String  name;
    private Integer status;
    private String updated_at;

    private AssetRate assetRate;
    private AssetCategory assetCategory;
    private Links links;
    private Self self;
    private AssetBrand assetBrand;
    private HasLinked hasLinked;


    public Integer getId_asset() {
        return id_asset;
    }

    public void setId_asset(Integer id_asset) {
        this.id_asset = id_asset;
    }

    public Integer getId_category() {
        return id_category;
    }

    public void setId_category(Integer id_category) {
        this.id_category = id_category;
    }

    public Integer getId_brand() {
        return id_brand;
    }

    public void setId_brand(Integer id_brand) {
        this.id_brand = id_brand;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(String updated_at) {
        this.updated_at = updated_at;
    }

    public AssetRate getAssetRate() {
        return assetRate;
    }

    public void setAssetRate(AssetRate assetRate) {
        this.assetRate = assetRate;
    }

    public AssetCategory getAssetCategory() {
        return assetCategory;
    }

    public void setAssetCategory(AssetCategory assetCategory) {
        this.assetCategory = assetCategory;
    }

    public Links getLinks() {
        return links;
    }

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

    public Self getSelf() {
        return self;
    }

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

    public AssetBrand getAssetBrand() {
        return assetBrand;
    }

    public void setAssetBrand(AssetBrand assetBrand) {
        this.assetBrand = assetBrand;
    }

    public HasLinked getHasLinked() {
        return hasLinked;
    }

    public void setHasLinked(HasLinked hasLinked) {
        this.hasLinked = hasLinked;
    }
}

AssetRate.class

public class AssetRate {

        private Integer id_asset_rate;
        private Integer id_asset;
        private Double value;
        private Double loan_to_value;
        private Double offered;
        private Double annual_rate;
        private String updated_at;

        public Integer getId_asset_rate() {
            return id_asset_rate;
        }

        public void setId_asset_rate(Integer id_asset_rate) {
            this.id_asset_rate = id_asset_rate;
        }

        public Integer getId_asset() {
            return id_asset;
        }

        public void setId_asset(Integer id_asset) {
            this.id_asset = id_asset;
        }

        public Double getValue() {
            return value;
        }

        public void setValue(Double value) {
            this.value = value;
        }

        public Double getLoan_to_value() {
            return loan_to_value;
        }

        public void setLoan_to_value(Double loan_to_value) {
            this.loan_to_value = loan_to_value;
        }

        public Double getOffered() {
            return offered;
        }

        public void setOffered(Double offered) {
            this.offered = offered;
        }

        public Double getAnnual_rate() {
            return annual_rate;
        }

        public void setAnnual_rate(Double annual_rate) {
            this.annual_rate = annual_rate;
        }

        public String getUpdated_at() {
            return updated_at;
        }

        public void setUpdated_at(String updated_at) {
            this.updated_at = updated_at;
        }
    }

像上面一样分离你的内心阶级。 如果您正在处理大型项目,那么分离内部类模型将非常有用。 你不必再次编写相同的pojo类。 你可以使用这个单独的类结构。

您可以使用此站点生成POJO类。 只需输入您的JSON响应并选择您使用的JSON类型,如GSON,Jackson.etc。 你会得到完美的POJO课程。 无需改变任何东西。

http://www.jsonschema2pojo.org/

您的Retrofit界面应该是

@GET("url") Call<List<AssetReponse>> getAssessList();

并确保您的变量名与 JSON响应中的键相同或者您可以使用注释@SerializedName来使其变得简单,您可以使用JSON到POJO在线转换器: http//www.jsonschema2pojo.org/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM