我目前正在使用GSON使用输入流/阅读器解析一个非常大的JSON文件。 在我的Android设备上解析大约需要35秒,我从一些基准测试中了解到Jackson性能更好。但我无法找到如何使用jackson解析我的JSON文件。任何人都可以帮助我吗?
我的JSON看起来像这样:
[
{
"venue": { … }
},
{
"venue": {
"venue_seasons": [ … ],
"address": "the address",
"city": "the city",
"name": "the name",
"created_at": "2011-05-31T07:55:33Z",
"latitude": 00.000000,
"country": "the country",
"internal_link_en": null,
"internal_link_nl": null,
"updated_at": "2011-09-15T14:46:09Z",
"zipcode": "the zipcode",
"foursquare_link": "foursquare url",
"url": null,
"id": 3,
"tip": "some tip",
"uid": "4ab5e205f964a520317620e3",
"phone": "phonenr",
"recommended": null,
"website": "someurl",
"venue_photos": [ … ], //array containing objects with urls of images
"description": null,
"longitude": 00.000000,
"thumbnail_location": null,
"subcategories": [ … ],
"opening_en": null,
"opening_nl": null,
"hidden": false,
"twitter": "thetwitteraccount",
"themes": [ … ]
}
}, //more venues
]
我的GSON代码看起来像这样,它有效:
AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open("filename.json");
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
Reader reader = new InputStreamReader(inputStream);
Gson gson = new Gson();
List<JsonResponse> venueList = gson.fromJson(reader, new TypeToken<List<JsonResponse>>() {}.getType());
JsonResponse naam = venueList.get(12);
String denaam = naam.venue.getName;
Log.i("nr12",denaam);
Log.i("timetracker","stop" );
// just some logging to test if the parser works
for (JsonResponse venue : venueList) {
String tijdel = String.valueOf(venue.venue.id);
Log.i(venuetag,"name of venue"+ tijdel+ " is: " + venue.venue.getName);
}
...
class JsonResponse
{
Venues venue;
}
class Venues
{
public List<VenueSeasons> venue_seasons;
public List<VenuePhotos> venue_photos;
public List<SubCategories> subcategories;
public List<Themes> themes;
@SerializedName("address")
public String getAdress;
@SerializedName("city")
public String getCity;
@SerializedName("country")
public String getCountry;
@SerializedName("name")
public String getName;
@SerializedName("created_at")
public Date getCreatedAt;
@SerializedName("updated_at")
public Date getUpdatedAt;
@SerializedName("internal_link_nl")
public String getInternalLinkNl;
@SerializedName("internal_link_en")
public String getInternalLinkEN;
@SerializedName("latitude")
public Double getLatitude;
@SerializedName("longitude")
public Double getLongitude;
@SerializedName("foursquare_link")
public String getFoursquareLink;
@SerializedName("url")
public String getURL;
@SerializedName("phone")
public String getPhone;
@SerializedName("zipcode")
public String getZipCode;
public String tip;
public String tip_en;
public String uid;
public int id;
@SerializedName("website")
public String getWebsite;
@SerializedName("recommended")
public Boolean getRecommended;
@SerializedName("description")
public String getDescription;
@SerializedName("hidden")
public Boolean getHidden;
@SerializedName("opening_en")
public String getOpeningEN;
@SerializedName("opening_nl")
public String getOpeningNL;
@SerializedName("twitter")
public String getTwitter;
@SerializedName("thumbnail_location")
public String getThumbnailLocation;
}
public class VenuePhotos
{
@SerializedName("large")
public String getLargePhotoURL;
@SerializedName("medium")
public String getMediumPhotoURL;
@SerializedName("small")
public String getSmallPhotoURL;
@SerializedName("original")
public String getOriginalPhotoURL;
public String uid;
public int id;
public int venue_id;
public boolean selected;
@SerializedName("created_at")
public Date getCreatedAt;
@SerializedName("updated_at")
public Date getUpdatedAt;
}
现在这个有效。我做了一些关于数据的东西,解析后它的工作效果都很棒,但是我觉得应用程序启动时间太长了。
我的杰克逊代码(失败的代码)是:
AssetManager assetManager = getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open("originalDelftJson.json");
} catch (IOException e) {
Log.e("tag", e.getMessage());
}
Reader reader = new InputStreamReader(inputStream);
ObjectMapper objectMapper = new ObjectMapper();
JsonFactory jsonFactory = new JsonFactory();
JJsonResponse response = null;
try {
JsonParser jp = jsonFactory.createJsonParser(reader);
response = objectMapper.readValue(jp, JJsonResponse.class);
String test = String.valueOf(response.venue.size());
使用课程:
public class JJsonResponse
{
public List<JVenue> venue;
}
class Venues
{
public List<VenueSeasons> venue_seasons;
public List<VenuePhotos> venue_photos;
public List<SubCategories> subcategories;
public List<Themes> themes;
@SerializedName("address")
public String getAdress;
@SerializedName("city")
public String getCity;
@SerializedName("country")
public String getCountry;
@SerializedName("name")
public String getName;
@SerializedName("created_at")
public Date getCreatedAt;
@SerializedName("updated_at")
public Date getUpdatedAt;
@SerializedName("internal_link_nl")
public String getInternalLinkNl;
@SerializedName("internal_link_en")
public String getInternalLinkEN;
@SerializedName("latitude")
public Double getLatitude;
@SerializedName("longitude")
public Double getLongitude;
@SerializedName("foursquare_link")
public String getFoursquareLink;
@SerializedName("url")
public String getURL;
@SerializedName("phone")
public String getPhone;
@SerializedName("zipcode")
public String getZipCode;
public String tip;
public String tip_en;
public String uid;
public int id;
@SerializedName("website")
public String getWebsite;
@SerializedName("recommended")
public Boolean getRecommended;
@SerializedName("description")
public String getDescription;
@SerializedName("hidden")
public Boolean getHidden;
@SerializedName("opening_en")
public String getOpeningEN;
@SerializedName("opening_nl")
public String getOpeningNL;
@SerializedName("twitter")
public String getTwitter;
@SerializedName("thumbnail_location")
public String getThumbnailLocation;
}
public class JVenue
{
public String name;
public int id;
public String city;
public String address;
public String country;
public String internal_link_nl;
public String internal_link_en;
public String zipcode;
public String foursquare_link;
public String tip_en;
public String url;
public Date created_at;
public Date updated_at;
public float latitude;
public float longitude;
public String tip;
public String uid;
public String phone;
public String recommended;
public String website;
public String description;
public String thumbnail_location;
public boolean hidden;
public String twitter;
public String opening_en;
public String opening_nl;
}
我认为我非常接近,但我做错了,因为我收到了错误:org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of com.jacksonrecipes.testapp.model.JJsonResponse out of START_ARRAY token
我真的不了解杰克逊的工作方式以及如何实施杰克逊。有谁知道如何在我的Android代码中更改我的Jackson实现,以便它可以工作,我可以访问数据?
编辑:获得我的解决方案
借助MH的答案。我能找到它。我现在用:
List<JJsonResponse> venueCounter = objectMapper.readValue(inputStream, new TypeReference<List<JJsonResponse>>() { });
答案 0 :(得分:5)
以下是使用Jackson的一个工作示例,其中原始问题中的JSON(已更正为有效且与Java数据结构相匹配)与来自原始Gson示例的Java数据结构(已更正为使用Jackson的{{1而不是Gson的@JsonProperty
)。
@SerializedName
答案 1 :(得分:4)
要记住的一件非常重要的事情是,您总是希望重用ObjectMapper
个实例 - 每个请求创建一个实例会减少很多事情,可能会减少一个数量级。通常只需创建一个静态实例(在创建后立即配置),或者通过像Guice这样的DI框架注入一个静态实例。
杰克逊的其他表现最佳做法可以在以下网址找到:http://wiki.fasterxml.com/JacksonBestPracticesPerformance
答案 2 :(得分:1)
看起来你的Json内容只是一个对象列表。这意味着,从我的头脑中,你的代码需要看起来像这样:
List<JVenue> venues = mapper.readValue(inputStream, new TypeReference<List<JVenue>>() { });
无需将InputStream
包裹在Reader
中,也无需创建自己的JsonFactory
和JsonParser
个实例。