我正在使用Flickr API。调用该flickr.test.login方法时,默认的JSON结果为:
flickr.test.login
{ "user": { "id": "21207597@N07", "username": { "_content": "jamalfanaian" } }, "stat": "ok" }
我想将此响应解析为Java对象:
public class FlickrAccount { private String id; private String username; // ... getter & setter ... }
JSON属性应按以下方式映射:
"user" -> "id" ==> FlickrAccount.id "user" -> "username" -> "_content" ==> FlickrAccount.username
不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a Map<String, Object>并从中获取值。
Map<String, Object>
Map<String, Object> value = new ObjectMapper().readValue(response.getStream(), new TypeReference<HashMap<String, Object>>() { }); @SuppressWarnings( "unchecked" ) Map<String, Object> user = (Map<String, Object>) value.get("user"); String id = (String) user.get("id"); @SuppressWarnings( "unchecked" ) String username = (String) ((Map<String, Object>) user.get("username")).get("_content"); FlickrAccount account = new FlickrAccount(); account.setId(id); account.setUsername(username);
但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器?
这对我来说将是很明显的,但是当然不起作用:
public class FlickrAccount { @JsonProperty( "user.id" ) private String id; @JsonProperty( "user.username._content" ) private String username; // ... getter and setter ... }
您可以为此类编写自定义解串器。它可能看起来像这样:
class FlickrAccountJsonDeserializer extends JsonDeserializer<FlickrAccount> { @Override public FlickrAccount deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { Root root = jp.readValueAs(Root.class); FlickrAccount account = new FlickrAccount(); if (root != null && root.user != null) { account.setId(root.user.id); if (root.user.username != null) { account.setUsername(root.user.username.content); } } return account; } private static class Root { public User user; public String stat; } private static class User { public String id; public UserName username; } private static class UserName { @JsonProperty("_content") public String content; } }
之后,您必须为您的类定义一个反序列化器。您可以按照以下步骤进行操作:
@JsonDeserialize(using = FlickrAccountJsonDeserializer.class) class FlickrAccount { ... }