我目前正在使用GSON使用inputstream/reader解析一个相当大的JSONfile。在我的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.JsonMappingExc0019:不能反序列化实例com.jacksonrecipes.testapp.model.JJsonRestor-outSTART_ARRAY令牌
我真的不明白杰克逊是如何工作的,以及如何实施它。有人知道如何在我的Android代码中更改我的Jackson实现,这样它就可以工作,我可以访问数据吗?
编辑:找到我的解决方案了吗
借助MH的回答。我能找到它。我现在使用:
List<JJsonResponse> venueCounter = objectMapper.readValue(inputStream, new TypeReference<List<JJsonResponse>>() { });
看起来Json内容只是一个对象列表。这意味着,在我看来,您的代码需要如下所示:
List<JVenue> venues = mapper.readValue(inputStream, new TypeReference<List<JVenue>>() { });
不需要将InputStream
包装到Reader
中,也不需要创建自己的JsonFactory
和JsonParser
实例。
需要记住的一件非常重要的事情是,您总是希望重用ObjectMapper
实例——每个请求创建一个实例会大大降低速度,可能会降低一个数量级。通常,要么只创建一个静态实例(在创建之后立即配置),要么通过DI框架(如Guice)注入一个静态实例。
杰克逊的其他最佳性能实践可以从以下网站找到:http://wiki.fasterxml.com/JacksonBestPracticesPerformance
以下是使用Jackson的工作示例,在原始问题中使用JSON(更正为有效并匹配Java数据结构),使用原始Gson示例中的Java数据结构(更正为使用Jackson的@JsonProperty
而不是Gson的@SeriazedName
)。
import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY;
import static com.fasterxml.jackson.annotation.PropertyAccessor.FIELD;
import java.io.File;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper().setVisibility(FIELD, ANY);
List<JsonResponse> responses = mapper.readValue(new File("input.json"), new TypeReference<List<JsonResponse>>() {});
System.out.println(responses);
System.out.println(mapper.writeValueAsString(responses));
}
}
class JsonResponse
{
Venues venue;
@Override
public String toString()
{
return venue.toString();
}
}
class Venues
{
List<VenueSeasons> venue_seasons;
@JsonProperty("address") String getAdress;
@JsonProperty("city") String getCity;
@JsonProperty("name") String getName;
@JsonProperty("created_at") Date getCreatedAt;
@JsonProperty("latitude") Double getLatitude;
@JsonProperty("country") String getCountry;
@JsonProperty("internal_link_en") String getInternalLinkEN;
@JsonProperty("internal_link_nl") String getInternalLinkNl;
@JsonProperty("updated_at") Date getUpdatedAt;
@JsonProperty("zipcode") String getZipCode;
@JsonProperty("foursquare_link") String getFoursquareLink;
@JsonProperty("url") String getURL;
int id;
String tip;
String uid;
@JsonProperty("phone") String getPhone;
@JsonProperty("recommended") Boolean getRecommended;
@JsonProperty("website") String getWebsite;
List<VenuePhotos> venue_photos;
@JsonProperty("description") String getDescription;
@JsonProperty("longitude") Double getLongitude;
@JsonProperty("thumbnail_location") String getThumbnailLocation;
List<SubCategories> subcategories;
@JsonProperty("opening_en") String getOpeningEN;
@JsonProperty("opening_nl") String getOpeningNL;
@JsonProperty("hidden") Boolean getHidden;
@JsonProperty("twitter") String getTwitter;
List<Themes> themes;
String tip_en; // not in example JSON
@Override
public String toString()
{
return String.format("Venues: id=%d", id);
}
}
class VenuePhotos
{
@JsonProperty("large") String getLargePhotoURL;
@JsonProperty("medium") String getMediumPhotoURL;
@JsonProperty("small") String getSmallPhotoURL;
@JsonProperty("original") String getOriginalPhotoURL;
String uid;
int id;
int venue_id;
boolean selected;
@JsonProperty("created_at") Date getCreatedAt;
@JsonProperty("updated_at") Date getUpdatedAt;
}
enum VenueSeasons
{
Spring, Summer, Fall, Winter
}
enum SubCategories
{
SubCat1, SubCat2, SubCat3, SubCat4
}
enum Themes
{
Theme1, Theme2, Theme3, Theme4
}
问题内容: 我想从类型为的JSON解析数据。我正在使用Google Gson。 我有: 我的课是: 问题答案: 这是执行此操作的简单代码,我避免了所有检查,但这是主要思想。 为了使使用更加通用- 您会发现Gson的javadocs非常清楚并且很有帮助。
问题内容: 我想使用Api GSON通过java解析JSON文件以获取JSON文件的最后一个字段: 描述符.json: ListTeleServices.java: TeleService.java: Record.java: 最后是我的解析器类 JSONMainParse.java: 对我来说似乎正确,它应该显示:“ amine1”,但它在以下位置给了我一个 nullPointerExcepti
问题内容: 我有一堂课,里面也有变量。有时我想忽略某些字段,有时在反序列化时不想忽略(也许也在序列化时)。在Jackson怎么办? 问题答案: 对于序列化,“ 过滤属性 ”博客条目应该会有所帮助。反序列化方面的支持较少,因为更常见的是要过滤掉所写的内容。 一种可能的方法是子类化,重写使方法(和/或字段)具有可忽略性的方法,以使用所需的任何逻辑。 如果您举了一个实际应用的例子,这也可能会有所帮助,即
问题内容: 假设我正在使用Google的Gson库将JSON解析为Java数据结构。 如果Java字段没有对应的JSON,是否有一种简单的引发异常的方法?也就是说,我希望要求JSON具有Java结构中的所有字段。 问题答案: Gson没有JSON模式验证功能来指定必须存在一个特定的元素,也没有办法指定必须填充Java成员。拥有这样的功能(例如带有注释)可能会很好。转到“ Gson问题列表” 并提出
如何使用GSON解析这个json? 我的代码: 我的stacktrace com.google.gson.JsonSyn出租车异常:java.lang.IllegalStateExctive:预期BEGIN_OBJECT但BEGIN_ARRAY在第1行第2列路径$com.google.gson.internal.bind.ReflecteTypeAdapterFactory$Adapter.rea
我正在尝试将JSON转换为GSON,我不确定这是最好的结构。 所有响应都由代码、消息和数据结构组成。但数据的内部结构可能会有所不同。 这是我的回应对象