[英]How to skip wrapper object in jackson json deserialization
我正在嘗試使用 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 apis 的響應。 我在包裝數組的包裝器對象上遇到問題。 這里
"broadcastPresenceRoles": {
"broadcastPresenceRole": [
"moderator",
"participant",
"visitor"
]
},
我試圖用這個來打開容器,但沒有成功。 我不認為編寫包裝類是個好主意(因為我將不得不編寫幾個包裝類)。此外,我需要通用解決方案,以便我可以將它與其他響應一起使用,因為 apis 具有類似包裝對象格式的其他響應. 提前致謝。
您可以在內部使用@JsonDeserialize
創建自定義注釋,並創建一個實現ContextualDeserializer
的自定義JsonDeserializer
。 這個想法的靈感來自您提到的解決方案,但在 json 對象中解包任何一個屬性更為通用。
以下是使用@JacksonAnnotationsInside
作為注釋容器包含@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 對象並將屬性提取到注釋字段中。
編輯:
以下是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());
輸出:
[主持人、參與者、訪客]
sanjeet@shahanshah
我創建了一個基於@wilson 響應解決 NPE 的變體
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonDeserialize(using = JsonUnwrapProperty.JsonUnwrapPropertyDeserializer.class)
public @interface JsonUnwrapProperty {
public static 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 {
System.out.println(String.format("Ignoring %s in %s/%s", unwrappedProperty,
jsonParser.currentName(), jsonParser.nextFieldName()));
JsonToken token = jsonParser.nextValue();
return jsonParser.getCodec().readValue(jsonParser, unwrappedJavaType);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.