3

ジャクソンを使用して次の文字列を逆シリアル化しようとしています。

{
  "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 レスト API からの応答です。配列をラップするラッパー オブジェクトに問題があります。ここ

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

これを試してコンテナをアンラップしましたが、成功しませんでした。ラッパークラスを書くことは良い考えではないと思います(いくつかのラッパークラスを書く必要があるため)。また、APIが同様のラップされたオブジェクト形式で他の応答を持っているため、他の応答で使用できるように一般化されたソリューションが必要です. 前もって感謝します。

4

2 に答える 2

4

@JsonDeserializeinside を使用してカスタム アノテーションを作成し、JsonDeserializerを実装するカスタムを作成できますContextualDeserializerこのアイデアは、あなたが言及したソリューションから着想を得ていますが、json オブジェクトの任意の 1 つのプロパティをアンラップする方が一般的です。

@JacksonAnnotationsInside以下は、注釈コンテナの内容として使用するカスタム注釈@JsonDeserializeです。

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonDeserialize(using = JsonUnwrapPropertyDeserializer.class)
public @interface JsonUnwrapProperty {
}

JsonDeserializerおよび実装するカスタムContextualDeserializer:

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

于 2016-07-31T03:54:09.187 に答える
0

@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);
    }
  }
}
于 2021-03-28T12:40:42.310 に答える