如何在杰克逊JSON反序列化中跳过包装对象 [英] How to skip wrapper object in jackson json deserialization
问题描述
我正在尝试使用杰克逊反序列化以下字符串.
I am trying to deserialize the following string using the jackson.
{
"roomName": "u8ec29p0j7q2m9f",
"broadcastPresenceRoles": {
"broadcastPresenceRole": [
"moderator",
"participant",
"visitor"
]
},
"owners": {
"owner": "anewuser@shahanshah"
},
"admins": {
"admin": "sanjeet@shahanshah"
},
"members": null,
"outcasts": {
"outcast": [
"sawan@shahanshah",
"sus@shahanshah"
]
},
"ownerGroups": {
"ownerGroup": "Friends"
}
}
这是来自openfire rest API的响应. 我在包装数组的包装对象时遇到问题. 在这里
This the response from the openfire rest apis. I am having problem with the wrapper object wrapping the arrays. Here
"broadcastPresenceRoles": {
"broadcastPresenceRole": [
"moderator",
"participant",
"visitor"
]
},
我尝试了此来打开容器的包装,但没有成功.我不认为编写包装器类是个好主意(因为我将不得不编写几个包装器类).我还需要通用的解决方案,以便我可以将其与其他响应一起使用,因为api具有类似包装对象格式的其他响应.预先感谢.
I tried this to unwrap the container but not getting success. I don't think writing wrapper classes is good idea (Since I will have to write several wrapper classes).Also I need the generalized solution so i can use it with other responses since the apis is having other responses in the similar wrapped objects format. Thanks in advance.
推荐答案
您可以在内部使用@JsonDeserialize
创建自定义注释,并创建实现ContextualDeserializer
的自定义JsonDeserializer
.这个想法的灵感来自您提到的解决方案在json对象中解包任何一个属性都比较普遍.
You can create a custom annotation with @JsonDeserialize
inside and create a custom JsonDeserializer
that implements ContextualDeserializer
. The idea is inspired from the solution you mentioned but it is more general to unwrap any one property in a json object.
以下是使用@JacksonAnnotationsInside
的自定义注释,因为注释容器包含@JsonDeserialize
:
Following is the custom annotation using @JacksonAnnotationsInside
as annotation container contains @JsonDeserialize
:
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonDeserialize(using = JsonUnwrapPropertyDeserializer.class)
public @interface JsonUnwrapProperty {
}
和实现ContextualDeserializer
的自定义JsonDeserializer
:
public class JsonUnwrapPropertyDeserializer extends JsonDeserializer<Object> implements ContextualDeserializer {
private JavaType unwrappedJavaType;
private String unwrappedProperty;
@Override
public JsonDeserializer<?> createContextual(final DeserializationContext deserializationContext, final BeanProperty beanProperty) throws JsonMappingException {
unwrappedProperty = beanProperty.getMember().getName();
unwrappedJavaType = beanProperty.getType();
return this;
}
@Override
public Object deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException {
final TreeNode targetObjectNode = jsonParser.readValueAsTree().get(unwrappedProperty);
return jsonParser.getCodec().readValue(targetObjectNode.traverse(), unwrappedJavaType);
}
}
和用法示例:
public class MyBean {
@JsonProperty("broadcastPresenceRoles")
@JsonUnwrapProperty
private List<String> broadcastPresenceRole;
@JsonProperty("admins")
@JsonUnwrapProperty
private String admin;
// constructor, getter and setter
}
@JsonProperty
用于定位包装对象,而@JsonUnwrappProperty
用于反序列化json对象并将属性提取到带注释的字段中.
@JsonProperty
is to locate the wrapper object and @JsonUnwrappProperty
is to deserialize the json object and extract a property into the annotated field.
已
以下是ObjectMapper
的示例:
String json = "{\n" +
" \"broadcastPresenceRoles\": {\n" +
" \"broadcastPresenceRole\": [\n" +
" \"moderator\",\n" +
" \"participant\",\n" +
" \"visitor\"\n" +
" ]\n" +
" },\n" +
" \"admins\": {\n" +
" \"admin\": \"sanjeet@shahanshah\"\n" +
" }\n" +
"}";
final ObjectMapper mapper = new ObjectMapper();
final MyBean myBean = mapper.readValue(json, MyBean.class);
System.out.println(myBean.getBroadcastPresenceRole());
System.out.println(myBean.getAdmin());
输出:
[主持人,参与者,访客]
[moderator, participant, visitor]
sanjeet @ shahanshah
sanjeet@shahanshah
这篇关于如何在杰克逊JSON反序列化中跳过包装对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!