如何在杰克逊JSON反序列化中跳过包装对象 [英] How to skip wrapper object in jackson json deserialization

查看:124
本文介绍了如何在杰克逊JSON反序列化中跳过包装对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用杰克逊反序列化以下字符串.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆