有一个问题here与我的问题相似,但不完全是我正在寻找的问题。
我是来自网络服务的JSON回复,让我们说this JSON response:
{
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : 45.5017123,
"lng" : -73.5672184
},
"southwest" : {
"lat" : 43.6533103,
"lng" : -79.3827675
}
},
"copyrights" : "Dados do mapa ©2015 Google",
"legs" : [
{
"distance" : {
"text" : "541 km",
"value" : 540536
},
"duration" : {
"text" : "5 horas 18 min.",
"value" : 19058
},
"end_address" : "Montreal, QC, Canada",
"end_location" : {
"lat" : 45.5017123,
"lng" : -73.5672184
},
"start_address" : "Toronto, ON, Canada",
"start_location" : {
"lat" : 43.6533103,
"lng" : -79.3827675
},
(...)
在这个JSON中我只对distance
对象感兴趣。我的问题是,如何忽略所有其他领域?
我尝试从legs
开始构建我的对象,因为它是从distance
到根的第一个非重复对象名称。
这是我的目标:
public class MyObject {
public ArrayList<Distance> legs;
public static class Distance {
public String text;
public String value;
}
}
但ArrayList legs
始终为null
。
我怎样才能做到这一点?忽略假装的json字段左侧的字段。
答案 0 :(得分:7)
我认为Gson的哲学是将Json结构映射到对象图。所以在你的情况下,我可能会创建所有需要的java对象来正确映射json结构。除此之外,也许有一天您需要一些其他的响应信息,因此进行演变会更容易。这样的事情(我认为正确的方式):
class RouteResponse {
private List<Route> routes;
}
class Route {
private List<Bound> bounds;
private String copyrights;
private List<Leg> legs;
}
class Leg {
private Distance distance;
private Duration duration;
private String endAddress;
...
}
class TextValue {
private String text;
private String value;
}
class Distance extends TextValue {
}
// And so on
我会使用ExclusionStrategy来制作轻物体,并且只使用我感兴趣的字段。听起来像是正确的方法。
现在,如果您确实只想检索距离列表,我们确定您可以使用自定义TypeAdapter和TypeAdapterFactory进行检索。
类似的东西(坏方法: - )):
映射响应的对象:
public class RouteResponse {
private List<Distance> distances;
// add getters / setters
}
public class Distance {
private String text;
private String value;
// add getters / setters
}
实例化我们的适配器的工厂(引用Gson
对象,因此适配器可以检索委托):
public class RouteResponseTypeAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getRawType() == RouteResponse.class) {
return (TypeAdapter<T>)new RouteResponseTypeAdapter(gson);
}
return null;
}
}
类型适配器:此实现将首先将Json文档解组为JsonElement
树,然后将检索所需的JsonObject
以通过委托创建Distance
个对象(对不起的代码感到抱歉,快速写完。)
public class RouteResponseTypeAdapter extends TypeAdapter<RouteResponse> {
private final TypeAdapter<JsonElement> jsonElementTypeAdapter;
private final TypeAdapter<Distance> distanceTypeAdapter;
public RouteResponseTypeAdapter(Gson gson) {
this.jsonElementTypeAdapter = gson.getAdapter(JsonElement.class);
this.distanceTypeAdapter = gson.getAdapter(Distance.class);
}
@Override
public void write(JsonWriter out, RouteResponse value) throws IOException {
throw new UnsupportedOperationException("Not implemented");
}
@Override
public RouteResponse read(JsonReader jsonReader) throws IOException {
RouteResponse result = new RouteResponse();
List<Distance> distances = new ArrayList<>();
result.setDistances(distances);
if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) {
JsonObject responseObject = (JsonObject) jsonElementTypeAdapter.read(jsonReader);
JsonArray routes = responseObject.getAsJsonArray("routes");
if (routes != null) {
for (JsonElement element:routes) {
JsonObject route = element.getAsJsonObject();
JsonArray legs = route.getAsJsonArray("legs");
if (legs != null) {
for (JsonElement legElement:legs) {
JsonObject leg = legElement.getAsJsonObject();
JsonElement distanceElement = leg.get("distance");
if (distanceElement != null) {
distances.add(distanceTypeAdapter.fromJsonTree(distanceElement));
}
}
}
}
}
}
return result;
}
}
最后,您可以解析您的json文档:
String json = "{ routes: [ ....."; // Json document
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new RouteResponseTypeAdapterFactory()).create();
RouteResponse response = gson.fromJson(json, RouteResponse.class);
//response.getDistances() should contain the distances
希望它有所帮助。