android - 如何在 jackson json 反序列化中跳过包装器对象

标签 android json jackson pojo jackson-dataformat-xml

我正在尝试使用 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 的响应。 我对包装数组的包装器对象有疑问。 这里

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

我试过了 this打开容器但没有成功。我不认为编写包装类是个好主意(因为我将不得不编写几个包装类)。我还需要通用的解决方案,以便我可以将它与其他响应一起使用,因为 api 具有类似包装对象格式的其他响应.提前致谢。

最佳答案

您可以在内部创建一个带有 @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是定位wrapper对象,@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());

输出:

[moderator, participant, visitor]

sanjeet@shahanshah

关于android - 如何在 jackson json 反序列化中跳过包装器对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38679451/

相关文章:

javascript - axios GET 请求有效,但无法将结果内容分配给变量

python - 将值添加到现有 json 文件而不重写它

java - 有没有办法让 jackson jsonize 只获取延迟加载的对象

ajax - 如何从 Laravel 中的函数传递 View 和 json?

java - 使用 Jackson 进行非对称序列化和反序列化

java - 使用 Jackson API 在 Java 中实现复杂的递归 JSON 响应

android - 每隔一分钟在背景中重复一次功能

android - ExoPlayer 使用自定义的 MediaCodecSelector

java - 聊天布局左、右与包裹背景对齐

xml - android包含标签 - 无效的布局引用