当前位置: 首页 > 知识库问答 >
问题:

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

弘焕
2023-03-14

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

我的目标

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

HTTP POST响应

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

   {"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编码的响应,然后将其更改为字符串,然后再次尝试访问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中,你可以这样做:费用[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对我来说没有什么是容易的!

共有3个答案

令狐灿
2023-03-14

>

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

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

    Gson gson = new Gson();              
    PostResponse response = gson.fromJson(result, PostResponse.class);
    System.out.println(result);
    

    }

    这个代码部分主要意味着,在获得web响应并获得字符串格式json响应的AsyncTask之后,这个onPostExecute将被该字符串化的json调用。

     Gson gson = new Gson();   
    

    Gson是谷歌支持的一个库,android可以将其反序列化到类对象中。

    gson.fromJson(result, PostResponse.class);
    

    这个方法是反序列化的真实过程。结果是Stringfiedjson,第二个是您要反序列化到的目标类。这将返回一个后置响应对象,您现在可以使用它了。

  • 蒲寂离
    2023-03-14
    1. 答案是肯定的,您将在InputStream中得到响应
    2. 关于第二个问题,请查看-jsonschema2pojo这在为JSON数据创建模型时会很有帮助

    然后使用GSON

    Gson gson = new Gson(); 
    YourObj yourObj = (YourObj) gson.fromJson(result, YourObj.class);
    
    牧业
    2023-03-14

    第一个问题

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

    这是处理http响应的一种方法。“json编码的响应”只不过是基于文本的响应,因此在接收端将其转换为字符串是有意义的。也就是说,就Java而言,您收到的json不是一个“对象”:它只是一个对象(或者您的例子中的一组对象)的文本表示,作为字节流接收。

    也就是说,可以通过跳过字符串(生成器)部分来缩短代码。Gson提供了另一个构造函数,它以读取器为例,您可以在代码片段中为其提供缓冲读取器

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

    第二个问题

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

    你已经接近了,但是如果你更仔细地观察json示例,你会发现你的PostSolutions类与它不太匹配:

    {
      "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)对象:expenseexpense_rec(都包含0…*元素,如方括号所示)。这意味着,无论您要将json映射到哪个类,都应该定义这些字段。如果你现在看看你的PostResponse类,很明显,在它当前的形式中,它实际上模拟了上述字段的一个子对象。

    基本上,要将json映射到的类应该如下所示:

    回复:

    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
    }
    

    定义了模型类后,试着让Gson再次发挥它的魔力。如果一切顺利,你应该能够以类似于PHP的方式访问数据:

    // 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();
    

    ... 或通过ExpenseItem中定义的getter的任何其他字段。

    一旦这个部分开始工作,就可以非常简单地向适配器提供数组或费用列表(请查看Android framenwork中的ArrayAdapter),并将该适配器绑定到ListView

     类似资料:
    • 问题内容: 我有一个像这样的JSON对象: 并尝试与Gson解析: 但是“ responceBean”始终为“ null” 这是所有其他类: 这是我的最新尝试。我不知何故找不到正确的方法。任何帮助将不胜感激。 问题答案: 您的 JSON模型与您的对象模型不匹配 。 您需要一个中间层来填补空白: TypeAdapter 。 而且,没有用户的命名信息。 最后是名称不匹配:JSON中的“ worklog

    • 我希望通过java使用Api GSON解析一个JSON文件,以获取JSON文件的最后字段: json: java:

    • 因此,我试图使用GSON解析Java中的JSON对象。我正在尝试从一个网站消费一个API。这是代码:https://api.coinmarketcap.com/v1/ticker/bitcoin/ JSON如下所示: 我正在使用Jersey来消费API,我想把这个JSON转换成一个对象。 这是应该通过解析JSON来构建的对象: 这是我的代码: 我有个错误 线程“main”com.google.gs

    • 问题内容: 我想使用Api GSON通过java解析JSON文件以获取JSON文件的最后一个字段: 描述符.json: ListTeleServices.java: TeleService.java: Record.java: 最后是我的解析器类 JSONMainParse.java: 对我来说似乎正确,它应该显示:“ amine1”,但它在以下位置给了我一个 nullPointerExcepti

    • 如何在Android中重新填充ListView 那是我的样本代码。我想重新填充的listview上的公共无效onTextChanged(CharSequence s, int start, int int count)function.ononTextChanged函数,我想填补listview与一个新的字符串数组。

    • 我正在使用来解析Json数据。我的Json数据如下: GsonParse.java 我使用以下方法来解析此JSON数据。 我面对以下错误。