在java中使用GSON解析JSON并填充列表视图

在java中使用GSON解析JSON并填充列表视图,java,android,json,gson,Java,Android,Json,Gson,我意识到我的问题被问了很多,但我花了相当多的时间搜索SO和google,试图更好地理解这个概念,但没有成功。我见过许多不同的实现,这使我得到了一些关于我的具体情况的建议 我的目标 我需要对php文件执行post请求,目标是最终使用一些json数据填充列表活动中的字段 HTTP POST响应 下面是我从服务器返回的响应数据的格式,它似乎是数组(?)的JSON对象 第一个问题 下面的代码是我用来读取响应的代码。我应该这样处理吗?获取一个json编码的响应,然后将其更改为字符串,然后再次尝试访问jso

我意识到我的问题被问了很多,但我花了相当多的时间搜索SO和google,试图更好地理解这个概念,但没有成功。我见过许多不同的实现,这使我得到了一些关于我的具体情况的建议

我的目标

我需要对php文件执行post请求,目标是最终使用一些json数据填充列表活动中的字段

HTTP POST响应

下面是我从服务器返回的响应数据的格式,它似乎是数组(?)的JSON对象

第一个问题

下面的代码是我用来读取响应的代码。我应该这样处理吗?获取一个json编码的响应,然后将其更改为字符串,然后再次尝试访问json对象的元素,这似乎很奇怪。我走错方向了吗

//This code is in the doInBackground method of my "sendPostRequest" async task.
HttpResponse httpResponse = httpClient.execute(httpPost);

InputStream inputStream = httpResponse.getEntity().getContent();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

StringBuilder stringBuilder = new StringBuilder();
String bufferedStrChunk = null;

while ((bufferedStrChunk = bufferedReader.readLine()) != null) {
      stringBuilder.append(bufferedStrChunk);
}
//Returns string to onPostExecute()
return stringBuilder.toString();
第二个问题

我有另一个名为“PostResponse.java”的文件,其中包含我根据在线教程建模的以下代码。我不确定如何从onPostExecute方法与这个类交互。我如何访问第一个对象中的第一项(类似于PHP中可以执行的操作:expense[0]['cat_name'])。我尝试过各种各样的方法,但都没有成功。以下是PostResponse.java类:

public class PostResponse {
public Integer cat_id_PK;
public String cat_name;
public BigDecimal cat_amount;
public Integer is_recurring;

public int getID() {
    return this.cat_id_PK;
}
public void setID(int cat_id_PK){
    this.cat_id_PK = cat_id_PK;
}

public String getName() {
    return this.cat_name;
}
public void setName(String cat_name) {
    this.cat_name = cat_name;
}

public BigDecimal getAmount() {
    return this.cat_amount;
}
public void setAmount(BigDecimal cat_amount) {
    this.cat_amount = cat_amount;
}

public int getRecurring() {
    return this.is_recurring;
}
public void setRecurring(int is_recurring) {
    this.is_recurring = is_recurring;
}

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("*** Categories ***");
    sb.append("cat_id_PK="+getID()+"\n");
    sb.append("cat_name="+getName()+"\n");
    sb.append("cat_amount="+getAmount()+"\n");
    sb.append("is_recurring="+getRecurring()+"\n");

    return sb.toString();
}
}

以下是我的onPostExecute方法的内容:

protected void onPostExecute(String result) {
    super.onPostExecute(result);

    Gson gson = new Gson();              
    PostResponse response = gson.fromJson(result, PostResponse.class);
    System.out.println(result);
}
正如我最初所说,我的最终目标是将这些项目填充到列表活动中,但在这一点上,我满足于只知道如何获取特定元素。然而,如果有人想在他们的响应中包括如何填充列表活动,这将为我省去更多的麻烦,因为java对我来说没有什么是容易的

  • 答案是肯定的。收到的响应为
    InputSteam

  • 受保护的void onPostExecute(字符串结果) { super.onPostExecute(结果)

    }

  • 此代码部分主要意味着在获得web响应和字符串格式json响应的
    AsyncTask
    之后,将使用该字符串化json调用此
    onPostExecute

     Gson gson = new Gson();   
    
    Gson是谷歌支持的一个库,android可以将其反序列化到类对象中

    gson.fromJson(result, PostResponse.class);
    
    此方法是反序列化的真实过程
    result
    是字符串化的json,第二个是要反序列化到的目标类。 这将返回一个PostResponse对象,您现在可以使用它。

    对于json数据(

    这里它包含两个不同的数组,一个是“expense”,另一个是“expense\u rec”。因此,如果要将这些项目填充到列表活动中,可以尝试以下方法

    protected void onPostExecute(String result) {
        super.onPostExecute(result);
    
        JSONObject jsonObject = new JSONObject(builder.toString());
        Log.i(TAG, "jsonObject is : " + jsonObject.toString());
    
        //this is the first array data 
        JSONArray jsonArray = jsonObject.getJSONArray("expense");
        Log.i(TAG, "Array length is: " + jsonArray.length());
    
        for(int i = 0; i < jsonArray.length(); i++){
            JSONObject jsoObj = jsonArray.getJSONObject(i);
            String name = jsoObj.getString("cat_name");
            Log.i(TAG, "file name is: " + name);
        }
    
        //this is the second array data 
        jsonArray = jsonObject.getJSONArray("expense_rec");
        for(int i = 0; i < jsonArray.length(); i++){
            JSONObject jsoObj = jsonArray.getJSONObject(i);
            String name = jsoObj.getString("cat_name");
            Log.i(TAG, "file name is: " + name);
        }
    }
    
    受保护的void onPostExecute(字符串结果){
    super.onPostExecute(结果);
    JSONObject JSONObject=新的JSONObject(builder.toString());
    i(标记“jsonObject is:”+jsonObject.toString());
    //这是第一个数组数据
    JSONArray JSONArray=jsonObject.getJSONArray(“费用”);
    i(标记,“数组长度为:”+jsonArray.length());
    for(int i=0;i
  • 答案是肯定的,您将在InputStream中得到响应
  • 对于您的第二个问题,请检查这个问题——这在为JSON数据创建模型时会很有帮助
  • 然后使用GSON

    Gson gson = new Gson(); 
    YourObj yourObj = (YourObj) gson.fromJson(result, YourObj.class);
    
    第一个问题

    下面的代码是我用来读取响应的代码。我应该这样处理吗?获取一个json编码的响应,然后将其更改为字符串,然后再次尝试访问json对象的元素,这看起来很奇怪。我是不是走错了路

    //This code is in the doInBackground method of my "sendPostRequest" async task.
    HttpResponse httpResponse = httpClient.execute(httpPost);
    
    InputStream inputStream = httpResponse.getEntity().getContent();
    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    
    StringBuilder stringBuilder = new StringBuilder();
    String bufferedStrChunk = null;
    
    while ((bufferedStrChunk = bufferedReader.readLine()) != null) {
          stringBuilder.append(bufferedStrChunk);
    }
    //Returns string to onPostExecute()
    return stringBuilder.toString();
    
    这是处理http响应的一种方法。“json编码的响应”只不过是基于文本的响应,因此在接收端将其转换为字符串是有意义的。也就是说,就Java而言,您接收的json不是一个“对象”:它只是一个对象(或您案例中的一组对象)的文本表示,作为字节流接收

    也就是说,您可以通过跳过字符串(生成器)部分来缩短代码。Gson提供了一个实例,您可以在代码片段中为其提供
    BufferedReader

    附带说明:将文本json转换为Java对象可能是一项“繁重”的操作。因此,最好避免在主/ui线程上执行此操作,因此只需将其移动到
    AsyncTask
    doInBackground()
    方法中(并适当更改类型)

    第二个问题

    我有另一个名为“PostResponse.java”的文件,其中包含我根据在线教程建模的以下代码。我不确定如何从onPostExecute方法与此类交互。我如何访问第一个对象中的第一项(类似于PHP中的操作:expense[0]['cat_name']).我尝试过各种方法,但都没有成功

    很接近,但是如果仔细查看json示例,您会发现您的
    PostResponse
    类与之不匹配:

    {
      "expense": [
        {
          "cat_id_PK": 237,
          "cat_name": "Name1",
          "cat_amount": "100.00",
          "is_recurring": 0
        },
        {
          "cat_id_PK": 238,
          "cat_name": "Name2",
          "cat_amount": "200.00",
          "is_recurring": 0
        },
        {
          "cat_id_PK": 239,
          "cat_name": "Name3",
          "cat_amount": "300.00",
          "is_recurring": 0
        },
        {
          "cat_id_PK": 240,
          "cat_name": "Name4",
          "cat_amount": "400.00",
          "is_recurring": 0
        }
      ],
      "expense_rec": [
        {
          "cat_id_PK": 207,
          "cat_name": "Name5",
          "cat_amount": "500.00",
          "is_recurring": 1
        }
      ]
    }
    
    考虑上面更层次化的格式。在第一级有两个(json)对象:
    expense
    expense\u rec
    (都包含0…*元素,如方括号所示)。这意味着无论您要将json映射到哪个类,都应该
    Gson gson = new Gson(); 
    YourObj yourObj = (YourObj) gson.fromJson(result, YourObj.class);
    
    {
      "expense": [
        {
          "cat_id_PK": 237,
          "cat_name": "Name1",
          "cat_amount": "100.00",
          "is_recurring": 0
        },
        {
          "cat_id_PK": 238,
          "cat_name": "Name2",
          "cat_amount": "200.00",
          "is_recurring": 0
        },
        {
          "cat_id_PK": 239,
          "cat_name": "Name3",
          "cat_amount": "300.00",
          "is_recurring": 0
        },
        {
          "cat_id_PK": 240,
          "cat_name": "Name4",
          "cat_amount": "400.00",
          "is_recurring": 0
        }
      ],
      "expense_rec": [
        {
          "cat_id_PK": 207,
          "cat_name": "Name5",
          "cat_amount": "500.00",
          "is_recurring": 1
        }
      ]
    }
    
    public class PostResponse {
    
        public ExpenseItem[] expense;
        public ExpenseItem[] expense_rec; 
        // List<ExpenseItem> is also supported
    
        // getters & setters
    }
    
    public class ExpenseItem {
    
        public Integer cat_id_PK;
        public String cat_name;
        public BigDecimal cat_amount;
        public Integer is_recurring;
    
        // getters & setters
    }
    
    // map json to POJOs
    PostResponse response = new Gson().fromJson(bufferedReader, PostResponse.class);
    // retrieve the cat_name for the first item (assuming there is one)
    String catName = response.getExpense()[0].getName();