GSON - JSON解析到对象时,忽略JSON领域 [英] Gson - ignore json fields when parsing JSON to Object
问题描述
{
路线:[
{
界限:{
东北:{
纬度:45.5017123,
LNG:-73.5672184
},
西南:{
纬度:43.6533103,
LNG:-79.3827675
}
},
版权:Dados做地图©2015谷歌
腿:
{
距离:{
文:541公里
值:540536
},
持续时间:{
文:5 horas 18分钟。
值:19058
},
END_ADDRESS:蒙特利尔,加拿大
END_LOCATION:{
纬度:45.5017123,
LNG:-73.5672184
},
START_ADDRESS:多伦多,加拿大
START_LOCATION:{
纬度:43.6533103,
LNG:-79.3827675
},
(......)
在此JSON我在距离
对象只是感兴趣。我的问题是,我怎么能忽略所有的其他领域?
我试图建立我的对象从腿开始
,因为它是从的第一个非重复的对象名称距离
到根。
下面是我的目标:
公共类为MyObject { 公众的ArrayList<距离和GT;双腿; 公共静态类的距离{
公共字符串文本;
公共字符串值;
}
}
但 ArrayList的腿
总是空
。
我怎样才能做到这一点?忽略字段从pretended JSON场左侧。
我认为GSON的理念是将JSON结构映射到对象图。所以你的情况我可能会创建所有需要的Java对象正确映射JSON结构。另外的,也许有一天你会需要响应的其他一些信息,所以这将是容易做的演变。类似的东西(适当的方式,我认为):
类RouteResponse {
私人列表<路线和GT;路线;
}
Route类{
私人列表<&约束GT;界限;
私人字符串版权;
私人列表<&腿GT;双腿;
}
一流的腿{
私人距离距离;
私人时间期限;
私人字符串endAddress;
...
}
类TextValue {
私人字符串文本;
私人字符串值;
}
距离类扩展TextValue {
}
// 等等
和我会用一个<一个href=\"http://google-gson.google$c$c.com/svn/trunk/gson/docs/javadocs/com/google/gson/ExclusionStrategy.html\"相对=nofollow> ExclusionStrategy 有灯光对象,并只有我感兴趣的领域。这听起来好像正确的方式做到这一点。
现在,如果你真的想只检索距离的名单,我相信你能做到这一点与自定义的 TypeAdapter 和<一个href=\"http://google-gson.google$c$c.com/svn/trunk/gson/docs/javadocs/com/google/gson/TypeAdapterFactory.html\"相对=nofollow> TypeAdapterFactory 。
类似的东西(坏的方式: - )):
的对象映射响应:
公共类RouteResponse { 私人列表&LT;距离和GT;距离; //添加getter / setter方法
}公共类距离{ 私人字符串文本;
私人字符串值; //添加getter / setter方法
}
这是我们的实例化适配器工厂(与在 GSON
对象的引用,因此适配器可以检索委托):
公共类RouteResponseTypeAdapterFactory实现TypeAdapterFactory { @覆盖
公众&LT; T&GT; TypeAdapter&LT; T&GT;创建(GSON GSON,TypeToken&LT; T&GT;类型){
如果(type.getRawType()== RouteResponse.class){
回报(TypeAdapter&LT; T&GT;)新RouteResponseTypeAdapter(GSON);
}
返回null;
}
}
和类型的适配器:此实现会先解组JSON文档到 JsonElement
取值树,然后将检索所需的的JSONObject
s到委托创建距离
对象(抱歉坏code,迅速写)。
公共类RouteResponseTypeAdapter扩展TypeAdapter&LT; RouteResponse&GT; { 私人最终TypeAdapter&LT; JsonElement&GT; jsonElementTypeAdapter;
私人最终TypeAdapter&LT;距离和GT; distanceTypeAdapter; 公共RouteResponseTypeAdapter(GSON GSON){
this.jsonElementTypeAdapter = gson.getAdapter(JsonElement.class);
this.distanceTypeAdapter = gson.getAdapter(Distance.class);
} @覆盖
公共无效写入(JsonWriter出来,RouteResponse值)抛出IOException
抛出新UnsupportedOperationException异常(未实现);
} @覆盖
公共RouteResponse读(JsonReader jsonReader)抛出IOException
RouteResponse结果=新RouteResponse();
清单&LT;距离和GT;距离=新的ArrayList&LT;&GT;();
result.setDistances(距离);
如果(jsonReader.peek()== JsonToken.BEGIN_OBJECT){
JSONObject的responseObject =(JSONObject的)jsonElementTypeAdapter.read(jsonReader);
JsonArray路线= responseObject.getAsJsonArray(路线);
如果(路线!= NULL){
对于(JsonElement元素:路由){
JSONObject的路线= element.getAsJsonObject();
JsonArray腿= route.getAsJsonArray(腿);
如果(腿!= NULL){
对于(JsonElement legElement:双腿){
JSONObject的腿= legElement.getAsJsonObject();
JsonElement distanceElement = leg.get(距离);
如果(distanceElement!= NULL){
distances.add(distanceTypeAdapter.fromJsonTree(distanceElement));
}
}
}
}
}
}
返回结果;
}
}
最后,你可以分析你的JSON文档:
JSON字符串={路线:[.....; // JSON文档
GSON GSON =新GsonBuilder()registerTypeAdapterFactory(新RouteResponseTypeAdapterFactory())创建()。
RouteResponse响应= gson.fromJson(JSON,RouteResponse.class);
//response.getDistances()应该包含的距离
希望它帮助。
There is a question here that is similar to my question but not exactly what I'm looking for.
I've a JSON response from a webservice, let's say 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
},
(...)
In this JSON I' just interested on the distance
object. My question is, how can I ignore all the other fields?
I tried to build my object starting from legs
, as it is the first non repetitive object name from distance
to the root.
Here's my object:
public class MyObject {
public ArrayList<Distance> legs;
public static class Distance {
public String text;
public String value;
}
}
but the ArrayList legs
is always null
.
How can I accomplish this? Ignore fields to the left from the pretended json field.
I think that the philosophy of Gson is to map the Json structure to an objects graph. So in your case I would probably create all the needed java objects to map correctly the json structure. In addition of that, maybe one day you will need some other information of the response, so it will be easier to do the evolution. Something like that (the proper way I think):
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
And I would use an ExclusionStrategy to have light objects and to have only the fields I'm interested in. It sounds to me like the proper way to do that.
Now if you really want to retrieve only the list of distances, I'm sure you can do that with a custom TypeAdapter and TypeAdapterFactory.
Something like that (the bad way :-)):
The objects to map the response:
public class RouteResponse {
private List<Distance> distances;
// add getters / setters
}
public class Distance {
private String text;
private String value;
// add getters / setters
}
The factory that instantiates our adapter (With a reference to the Gson
object, so the adapter can retrieve delegates) :
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;
}
}
And the type adapter: this implementation will first unmarshall the Json document to a JsonElement
s tree and then will retrieve the needed JsonObject
s to create through the delegate the Distance
objects (sorry for the bad code, quickly written).
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;
}
}
Finally, you can parse your json document:
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
Hope it helps.
这篇关于GSON - JSON解析到对象时,忽略JSON领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!