使用Jackson自定义JSON反序列化 [英] Custom JSON Deserialization with Jackson
问题描述
我正在使用 Flickr API 。致电 flickr.test.login $时c $ c>
方法,默认的JSON结果是:
I'm using the Flickr API. When calling the flickr.test.login
method, the default JSON result is:
{
"user": {
"id": "21207597@N07",
"username": {
"_content": "jamalfanaian"
}
},
"stat": "ok"
}
我是喜欢将此响应解析为Java对象:
I'd like to parse this response into a Java object:
public class FlickrAccount {
private String id;
private String username;
// ... getter & setter ...
}
JSON属性应该像这样映射:
The JSON properties should be mapped like this:
"user" -> "id" ==> FlickrAccount.id
"user" -> "username" -> "_content" ==> FlickrAccount.username
不幸的是,我无法找到一个漂亮,优雅的方法来执行此操作注释。到目前为止,我的方法是将JSON字符串读入 Map< String,Object>
并从那里获取值。
Unfortunately, I'm not able to find a nice, elegant way to do this using Annotations. My approach so far is, to read the JSON String into a Map<String, Object>
and get the values from there.
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);
但我认为,这是迄今为止最不优雅的方式。有没有简单的方法,使用Annotations还是自定义反序列化器?
But I think, this is the most non-elegant way, ever. Is there any simple way, either using Annotations or a custom Deserializer?
这对我来说非常明显,但当然不起作用:
This would be very obvious for me, but of course it doesn't work:
public class FlickrAccount {
@JsonProperty( "user.id" ) private String id;
@JsonProperty( "user.username._content" ) private String username;
// ... getter and setter ...
}
推荐答案
您可以为此类编写自定义反序列化程序。它可能如下所示:
You can write custom deserializer for this class. It could look like this:
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;
}
}
之后,你必须为你的班级定义序列化器。你可以这样做:
After that, you have to define serializer for your class. You can do this in this way:
@JsonDeserialize(using = FlickrAccountJsonDeserializer.class)
class FlickrAccount {
...
}
这篇关于使用Jackson自定义JSON反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!