【问题标题】:How to parse JSON Response with GSON (Java / Android)如何使用 GSON (Java / Android) 解析 JSON 响应
【发布时间】:2015-10-10 17:45:35
【问题描述】:

我只需要一个快速的建议,因为我是 JSON 的初学者。

我从网络服务器得到以下响应,我将其存储在字符串中:

{  
   "station62":[  
      {  
         "departureTime":1982,
         "delay":"-1.0",
         "line":"6",
         "stationName":"randomname",
         "direction":2
      }
   ],
   "station63":[  
      {  
         "departureTime":1234,
         "delay":"-1.0",
         "line":"87",
         "stationName":"anotherrandomname",
         "direction":2
      }
   ],
   "station64":[  
      {  
         "departureTime":4542,
         "delay":"-1.0",
         "line":"4",
         "stationName":"yetanotherrandomname",
         "direction":2
      }
   ],
   "station65":[  
      {  
         "departureTime":1232,
         "delay":"-1.0",
         "line":"23",
         "stationName":"onemorerandomname",
         "direction":2
      }
   ]
}

(对不起,我不知道这里的缩进是如何工作的。)

响应更长,但在本例中它被缩短了。所以我需要解析每个“站”对象的信息。 我不需要“station62”-String,我只需要 java-object 中的“departureTime”、“delay”、“line”、“stationName”和“direction”。

我已阅读此内容,但无法正常工作:https://stackoverflow.com/a/16378782

我是一个完全的初学者,所以非常感谢任何帮助。

编辑:这是我的代码:

我制作了一个包装类,就像上面的示例链接一样。我玩过一些地图类型,但到目前为止没有运气。

public class ServerResponse
{

private Map<String, ArrayList<Station>> stationsInResponse = new HashMap<String, ArrayList<Station>>();

public Map<String, ArrayList<Station>> getStationsInResponse()
{
    return stationsInResponse;
}

public void setStationsInResponse(Map<String, ArrayList<Station>> stationsInResponse)
{
    this.stationsInResponse = stationsInResponse;
}
}

问题是,这张地图没有被我在下面显示的 gson.fromJSON(...) 调用填充。地图大小始终为零。

Station 类如下所示:

public class Station
{
String line;
String stationName;
String departureTime;
String direction;
String delay;

// getters and setters are there aswell
}

而我想做的是

Gson gson = new Gson();
ServerResponse response = gson.fromJson(jsonString, ServerResponse.class);

其中“jsonString”包含 JSON 响应作为字符串。

我希望代码能显示我需要做什么,它应该很简单,但我在 JSON 中还不够好。

编辑 2

我需要这样的 JSON 吗?

{"stationsInResponse": {
"station62": [{
    "departureTime": 1922,
    "delay": "-1.0",
    "line": "8",
    "stationName": "whateverrandomname",
    "direction": 2
  }],
"station67": [{
    "departureTime": 1573,
    "delay": "-1.0",
    "line": "8",
    "stationName": "rndmname",
    "direction": 2
  }],
"station157": [{
    "departureTime": 1842,
    "delay": "-2.0",
    "line": "8",
    "stationName": "randomname",
    "direction": 2
  }]
}}

【问题讨论】:

  • 在您提到的答案的帮助下,您到目前为止所做的尝试。
  • 您应该在此处添加您的代码,以便我们为您提供帮助。
  • 我添加了一些代码,谢谢。
  • 但响应不是ServerResponse的类型,而是HashMap&lt;String, ArrayList&lt;Station&gt;&gt; ...在json中没有归档stationsInResponse
  • 所以我需要为我的地图提供与我的 JSON 文件中的名称相同的名称吗?问题是,我的 JSON 文件中的所有站点都被称为不同的站点,例如“station96”、“station 120”等等。

标签: java android json parsing gson


【解决方案1】:

这是工作代码:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.google.gson.Gson;

public class GSONTest {

    public static void main(String[] args){

        String gsonStr = "{\"stationsInResponse\": { \"station62\":[  {  \"departureTime\":1982,\"delay\":\"-1.0\",\"line\":\"6\",\"stationName\":\"randomname\",\"direction\":2} ],\"station63\":[  {  \"departureTime\":1981,\"delay\":\"-1.1\",\"line\":\"7\",\"stationName\":\"randomname2\",\"direction\":3} ]}}";

        Gson gson = new Gson();
        Response response = gson.fromJson(gsonStr, Response.class);

        System.out.println("Map size:"+response.getStationsInResponse().size());

        for (Iterator iterator = response.getStationsInResponse().keySet().iterator(); iterator.hasNext();) {

            String key = (String) iterator.next();

            ArrayList<Station> stationList = (ArrayList<Station>) response.getStationsInResponse().get(key);

            for (Iterator iterator2 = stationList.iterator(); iterator2.hasNext();) {

                Station station = (Station) iterator2.next();

                System.out.println("Delay: "+station.getDelay());
                System.out.println("DepartureTime: "+station.getDepartureTime());
                System.out.println("Line: "+station.getLine());
                System.out.println("StationName: "+station.getStationName());
            }


        }


    }


}

class Response {
      private Map<String, List<Station>> stationsInResponse;
      //getters and setters

    public Map<String, List<Station>> getStationsInResponse() {
        return stationsInResponse;
    }

    public void setStationsInResponse(Map<String, List<Station>> stationsInResponse) {
        this.stationsInResponse = stationsInResponse;
    }
    }

class Station {
      private String departureTime;
      public String getDepartureTime() {
        return departureTime;
    }
    public void setDepartureTime(String departureTime) {
        this.departureTime = departureTime;
    }
    public String getDelay() {
        return delay;
    }
    public void setDelay(String delay) {
        this.delay = delay;
    }
    public String getLine() {
        return line;
    }
    public void setLine(String line) {
        this.line = line;
    }
    public String getStationName() {
        return stationName;
    }
    public void setStationName(String stationName) {
        this.stationName = stationName;
    }
    public String getDirection() {
        return direction;
    }
    public void setDirection(String direction) {
        this.direction = direction;
    }
      private String delay;
      private String line;
      private String stationName;
      private String direction;

}

控制台的输出是这样的(因为我缩短了你的 json 字符串):

Map size:2
Delay: -1.0
DepartureTime: 1982
Line: 6
StationName: randomname
Delay: -1.1
DepartureTime: 1981
Line: 7
StationName: randomname2

【讨论】:

  • 是的,这就是那边提到的:stackoverflow.com/questions/16377754/parse-json-file-using-gson/… 我已经尝试过确切的方法,但地图仍然是空的。
  • 也不是。地图的每个值都是一个列表,而不是一个车站。
  • @hfbr ...更新了使用stationInResponse的第二个json的代码。
  • 感谢更新的答案。看起来它与@Nicklas回答的方法相同。我没有像在原始帖子的编辑中那样得到我的 JSON,但我认为这将是我需要的方式。我会看看为我提供 JSON 的人是否可以这样设置结构。
  • @hfbr 是的,这是根据edit2中提供的json
【解决方案2】:

首先我会指出你的错误,然后我会给你解决方案。

您在反序列化代码中要求的结构如下所示:

{
    "stationsInResponse": {
        "station1": [
            {
                "name": "Station 1"
            }
        ],
        "station2": [
            {
                "name": "Station 2"
            }
        ]
    }
}

解决方案

反序列化作为输入的结构真正需要的反序列化代码如下:

Gson gson = new Gson();
Type rootType = new TypeToken<Map<String, List<Station>>>(){}.getType();
Map<String, List<Station>> stationsMap = gson.fromJson(json, rootType);

这是因为一个 JSON 对象,其属性在编译时未知,即您的根对象,映射到 Java Map&lt;String, ?&gt;? 表示 JSON 对象值的预期 Java 类型,在您的情况下是 List&lt;Station&gt;Station[],无论您喜欢哪个。

如果您愿意,您可以将地图中的所有车站合并为一个 List 的车站,如下所示:

List<Station> stations = new ArrayList<>(stationsMap.size());
for (List<Station> stationsList : stationsMap.values()) {
    for (Station station : stationsList) {
        stations.add(station);
    }
}

【讨论】:

  • 感谢您的回答。问题是,在我的原始 JSON 中(请参阅我的第一篇文章中的原始 JSON),“stationsInResponse”不存在。 JSON 立即从某些站点对象开始。这是否正确我无法判断,但这是迄今为止向我提供 JSON 的方式。无论如何,如果我让我的 JSON 看起来像你的答案中使用的那样,我认为你的解决方案会起作用。还有一个问题:如果我从 JSON 中删除了所有 [ 和 ],那么反序列化所需的结构将只是 Map stationMap ,对吗?
  • 哦,还有一个问题。我发布的第一个 JSON(我原始帖子的顶部)也可以解析吗?因为您的答案是指第二个 JSON,到目前为止,生成该 JSON 的人似乎只能提供第一个的结构。
猜你喜欢
  • 2019-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多