2016-07-30 122 views
1

我想用jackson反序列化下面的字符串。如何跳过jackson json反序列化中的wrapper对象

{ 
    "roomName": "u8ec29p0j7q2m9f", 
    "broadcastPresenceRoles": { 
    "broadcastPresenceRole": [ 
     "moderator", 
     "participant", 
     "visitor" 
    ] 
    }, 
    "owners": { 
    "owner": "[email protected]" 
    }, 
    "admins": { 
    "admin": "[email protected]" 
    }, 
    "members": null, 
    "outcasts": { 
    "outcast": [ 
     "[email protected]", 
     "[email protected]" 
    ] 
    }, 
    "ownerGroups": { 
    "ownerGroup": "Friends" 
    } 
} 

这是来自openfire rest的回应apis。 我遇到包装数组的包装对象的问题。 这里

"broadcastPresenceRoles": { 
    "broadcastPresenceRole": [ 
     "moderator", 
     "participant", 
     "visitor" 
    ] 
    }, 

我试图this拆开包装容器,但没有得到成功。我不认为写封装类是好主意(因为我将不得不编写几个封装类)。我还需要广义的解决方案,因此我可以将它用于其他响应,因为apis在类似的包装对象格式中有其他响应。提前致谢。

回答

2

您可以使用里面的@JsonDeserialize创建自定义注释并创建实现ContextualDeserializer的自定义JsonDeserializer。这个想法的灵感来自于你提到的the solution,但是在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\": \"[email protected]\"\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

+0

我试过你建议的方式,我得到以下例外 - W/System.err:com.fasterxml.jackson.databind.JsonMappingException:(was java.lang.NullPointerException)(通过引用链:com.sked .jacksonparsingexample.entity.MyBean [“broadcastPresenceRoles”]) –

+0

引起:java.lang.NullPointerException 07-31 23:43:13.920 24840-24840/com.sked.jacksonparsingexample W/System.err:at com.sked。 jacksonparsingexample.util.JsonUnwrapPropertyDeserializer.deserialize(JsonUnwrapPropertyDeserializer.java:33) –

+0

我已经直接复制你给出的类,我已经尝试与两个属性只有json字符串。 –