【问题标题】:android studio json array responseandroid studio json数组响应
【发布时间】:2018-02-07 14:50:41
【问题描述】:

我一直在尝试通过 openweathermaps 从 API 获取 json 响应,但我似乎无法使其与 volley 或 Retrofit 一起使用,我将发布 volley 和 Retrofit 函数以及我在两者上遇到的错误以及json 消息本身

这是我试图捕获的 json 响应 http://samples.openweathermap.org/data/2.5/find?lat=55.5&lon=37.5&cnt=10&appid=b6907d289e10d714a6e88b30761fae22

这是 volley 代码“令人惊讶的是,我确实得到了我正在寻找的 json 的响应,但我在 on volley error msg 上得到了它”

RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

    // Initialize a new JsonArrayRequest instance
    JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
            Request.Method.GET,
            mJSONURLString,
            null,
            new Response.Listener<JSONArray>(){
                @Override
                public void onResponse(JSONArray response) {
                    textView.setText(response.toString());
                    try{
                        for(int i=0;i<response.length();i++){

                        }
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener(){
                @Override
                public void onErrorResponse(VolleyError error){
                    // this is where i get my json "how?"
                    System.out.println(error);
                }
            }
    );
    requestQueue.add(jsonArrayRequest);

这是一个完全不同的项目的改造代码“我正在测试两个 atm”

Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    CitiesArrayAPI service = retrofit.create(CitiesArrayAPI.class);
    Call<List<Cities>> call = service.loadCitiesFromAPI();
    call.enqueue(new Callback<List<Cities>>() {
        @Override
        public void onResponse(Response<List<Cities>> response, Retrofit retrofit) {
            System.out.println("test");
            try {
                List<Cities> cities = response.body();
                for (int i = 0; i < cities.size(); i++) {

                }
            } catch (Exception e) {
                Log.d("onResponse", "There is an error");
                e.printStackTrace();
            }
        }
        @Override
        public void onFailure(Throwable t) {
            Log.d("onFailure", t.toString());
        }
    });

这是arrayapi的改造接口

public interface CitiesArrayAPI {
@GET("data/2.5/find?lat=55.5&lon=37.5&cnt=5&appid=b6907d289e10d714a6e88b30761fae22")
Call<List<Cities>> loadCitiesFromAPI();

}

这是我从改造中得到的错误,适用于 onFailure 方法

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

【问题讨论】:

  • 看起来您没有以正确的格式投射该响应,因为您不仅获得了响应列表,因此您无法直接将该数据传递给列表。
  • 那么我如何同时读取一个对象和一个数组呢?
  • 如果我理解正确,那么你的意思是我没有单独获得列表 [],所以我应该找到一种方法来阅读整个内容,然后单独使用列表 [],对吗?
  • 是的,你应该使用 jsonschema2pojo.org 来对 java 类进行响应
  • 我不知道那是什么 tbh

标签: android json android-studio android-volley retrofit2


【解决方案1】:

您期望返回对象的列表的问题 所以改变改造接口返回对象而不是列表

public interface CitiesArrayAPI {
@GET("data/2.5/find?lat=55.5&lon=37.5&cnt=5&appid=b6907d289e10d714a6e88b30761fae22")
Call<Cities> loadCitiesFromAPI();
}

添加一个名为 Coord 的类

public class Coord {

@Expose
@SerializedName("lat")
private double lat;

@Expose
@SerializedName("lng")
private double lng;

private double getLat(){
    return lat;
}
 private double getLng(){
    return lng;
}
}

并创建具有坐标对象的对象 City

public class City {

@Expose
@SerializedName("coord")
private Coord coord;

private Coord getCoord(){
    return coord;
}
}

Cities 类是一个列表,这个对象是改造接口中调用的对象

public class Cities {

@SerializedName("cities")
private List<City> cities;
}

然后在响应中你可以调用

response.body.getCoord().getlat();

【讨论】:

  • 这与另一个答案几乎相同,它们都工作得很好,但我还有一个小问题,对于像 lat 和 lng 这样的东西,它们位于一个名为 coord 的数组中,我该如何管理得到那些
  • 不客气。如果它对你有用,请选择我的答案作为正确的答案。@MahmoudOmara P.S 你检查的答案不是我的。谢谢
  • tbh 这两个答案都起作用了,因为它是同一件事:P 但是你做了跟进,而他首先回答了 xD 我很困惑谁来验证作为答案,希望我能做到这两个
【解决方案2】:

您尝试解析的 json 肯定不是 List&lt;Cities&gt;,因此错误提示“您正在尝试解析数组但实际上有一个对象”

你的根对象应该是这样的

public class YouRootObject {

    @SerializedName("message")
    private String message;
    @SerializedName("cod")
    private String cod;
    @SerializedName("count")
    private Integer count;
    @SerializedName("list")
    private List<City> cities;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getCod() {
        return cod;
    }

    public void setCod(String cod) {
        this.cod = cod;
    }

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public List<City> getList() {
        return cities;
    }

    public void setList(List<City> cities) {
        this.cities = cities;
    }
}

然后你应该有&lt;YouRootObject&gt; 而不是&lt;List&lt;Cities&gt;&gt;

Call&lt;List&lt;Cities&gt;&gt; => Call&lt;YouRootObject&gt;Callback&lt;List&lt;Cities&gt;&gt; => Callback&lt;YouRootObject&gt;

【讨论】:

  • 这绝对是完美的,我现在将努力实现它,但是有一个简单的问题,我不希望所有变量都在列表中,所以在城市 java 类中我仍然需要声明所有这些还是只声明我想要的?
  • 好的,这可以完美地获取列表 [] 中的 id 和 name 等变量,但对于 lat 和 lng 等变量,它们位于名为 coord 的数组中,我如何设法获取这些变量
  • @MahmoudOmara 你可以跳过所有你不感兴趣的属性。对于像coordmain这样的嵌套条目,你必须创建适当的java对象。这是可以为您自动完成的站点jsonschema2pojo.org 只需将您的 json 复制粘贴到那里,在右侧面板上设置属性并生成对象。稍后谢谢我
猜你喜欢
  • 2022-01-10
  • 1970-01-01
  • 2017-01-05
  • 2018-12-18
  • 2018-12-12
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
相关资源
最近更新 更多