50
{
  vendors: [
    {
      vendor: {
        id: 367,
        name: "Kuhn-Pollich",
        company_id: 1,
      }
    },
    {
      vendor: {
        id: 374,
        name: "Sawayn-Hermann",
        company_id: 1,
      }
  }]
}

単一の「ベンダー」json から適切に逆シリアル化できる Vendor オブジェクトがありますが、これを に逆シリアル化したいのですが、Vendor[]Jackson を連携させる方法がわかりません。任意のヒント?

4

4 に答える 4

35

これは大雑把ですが、より宣言的な解決策です。1 つの注釈にまとめることができませんでしたが、これはうまく機能しているようです。また、大規模なデータ セットでのパフォーマンスについても不明です。

この JSON を考えると:

{
    "list": [
        {
            "wrapper": {
                "name": "Jack"
            }
        },
        {
            "wrapper": {
                "name": "Jane"
            }
        }
    ]
}

そして、これらのモデル オブジェクト:

public class RootObject {
    @JsonProperty("list")
    @JsonDeserialize(contentUsing = SkipWrapperObjectDeserializer.class)
    @SkipWrapperObject("wrapper")
    public InnerObject[] innerObjects;
}

public class InnerObject {
    @JsonProperty("name")
    public String name;
}

Jackson ブードゥー教が実装されている場所は次のとおりです。

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface SkipWrapperObject {
    String value();
}

public class SkipWrapperObjectDeserializer extends JsonDeserializer<Object> implements
        ContextualDeserializer {
    private Class<?> wrappedType;
    private String wrapperKey;

    public JsonDeserializer<?> createContextual(DeserializationContext ctxt,
            BeanProperty property) throws JsonMappingException {
        SkipWrapperObject skipWrapperObject = property
                .getAnnotation(SkipWrapperObject.class);
        wrapperKey = skipWrapperObject.value();
        JavaType collectionType = property.getType();
        JavaType collectedType = collectionType.containedType(0);
        wrappedType = collectedType.getRawClass();
        return this;
    }

    @Override
    public Object deserialize(JsonParser parser, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode objectNode = mapper.readTree(parser);
        JsonNode wrapped = objectNode.get(wrapperKey);
        Object mapped = mapIntoObject(wrapped);
        return mapped;
    }

    private Object mapIntoObject(JsonNode node) throws IOException,
            JsonProcessingException {
        JsonParser parser = node.traverse();
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(parser, wrappedType);
    }
}

これが誰かに役立つことを願っています!

于 2013-06-26T06:10:27.833 に答える
29

配列に内部ラッパーオブジェクトがあるという点で、データに問題があります。おそらく、Vendorオブジェクトは、、、を処理するように設計されてidいますがnamecompany_idこれらの複数のオブジェクトのそれぞれも、単一のプロパティを持つオブジェクトにラップされていますvendor

Jackson Data Bindingモデルを使用していると仮定しています。

その場合、次の 2 つの点を考慮する必要があります。

1 つ目は、特別な Jackson 構成プロパティを使用することです。Jackson - 1.9 以降、Jackson の古いバージョンを使用している場合、これは利用できない可能性があると思います - provides UNWRAP_ROOT_VALUE. これは、破棄したい最上位の単一プロパティ オブジェクトに結果がラップされている場合のために設計されています。

だから、遊んでください:

objectMapper.configure(SerializationConfig.Feature.UNWRAP_ROOT_VALUE, true);

2 つ目は、ラッパー オブジェクトを使用することです。外側のラッパー オブジェクトを破棄した後でも、Vendorオブジェクトが単一のプロパティ オブジェクトにラップされるという問題が残っています。これを回避するには、ラッパーを使用します。

class VendorWrapper
{
    Vendor vendor;

    // gettors, settors for vendor if you need them
}

同様に、 を使用する代わりにUNWRAP_ROOT_VALUES、外側のオブジェクトを処理するラッパー クラスを定義することもできます。Vendor正しい,オブジェクトがあると仮定すると、次のようVendorWrapperに定義できます。

class VendorsWrapper
{
    List<VendorWrapper> vendors = new ArrayList<VendorWrapper>();

    // gettors, settors for vendors if you need them
}

// in your deserialization code:
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readValue(jsonInput, VendorsWrapper.class); 

VendorsWrapper のオブジェクト ツリーは、JSON に似ています。

VendorsWrapper:
    vendors:
    [
        VendorWrapper
            vendor: Vendor,
        VendorWrapper:
            vendor: Vendor,
        ...
    ]

最後に、Jackson Tree Modelを使用して、これを に解析しJsonNodes、外側のノードを破棄して、 のそれぞれJsonNodeについて、次のArrayNodeように呼び出します。

mapper.readValue(node.get("vendor").getTextValue(), Vendor.class);

これによりコードが少なくなる可能性がありますが、2 つのラッパーを使用する場合と同じように扱いにくいようです。

于 2012-07-31T20:11:32.597 に答える