3

次の形式で配列を返す Web サービスを参照しています。

{
    "ZooAnimals": {
        "@size": "2",
        "Animal": {
            "0": {
                "@name": "elephant",
                "@size": "huge"
            },
            "1": {
                "@name": "termite",
                "@size": "verysmall"
            }
        }
    }
}

XML形式で要求された場合、次のものが返されます。

<ZooAnimals size="2">
    <Animal name="elephant" size="huge"></Animal>
    <Animal name="termite" size="very small"></Animal>
</ZooAnimals>

クラスに正しく逆シリアル化されることを確認するテストを作成していますJava。はXML正しく動作しますが、JSON(jackson を使用して) エラーが発生します: 認識されないフィールド "0" は無視できるものとしてマークされていません。

私は JSON 応答を制御しません。逆シリアル化されたコンテンツを受け取るために単一のクラスを使用したいと考えています。私が継承したクラスには、次のように注釈が付けられました。

@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonTypeName("ZooAnimals")
public class ZooAnimals {

    @XmlAttribute
    @JsonProperty("@size")
    private String size;

    @XmlElement(name = "Animal", required = false)
    @JsonProperty("Animal")
    private List<Animal> animalList;
...
}

@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonTypeName("Animal")
public class Animal {

    @XmlAttribute
    @JsonProperty("@name")
    private String name;

    @XmlAttribute
    @JsonProperty("@size")
    private String size;
...
}

このクラスに注釈を付けて、jackson がカスタム コードを記述しなくても上記のテキストを逆シリアル化できるようにする方法はありますか? 余談ですが、順序を維持することは必須ではありません。

4

1 に答える 1

3

JsonAnySetter注釈を使用する必要があり、ZooAnimalsクラスは次のようになります。

@XmlAccessorType(XmlAccessType.FIELD)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonTypeName("ZooAnimals")
class ZooAnimals {

    @XmlAttribute
    @JsonProperty("@size")
    private String size;

    @XmlElement(name = "Animal", required = false)
    private List<Animal> animalList;

    @JsonAnySetter
    public void setAny(String propertyName, Map<String, Animal> map) {
        animalList = new ArrayList<Animal>(map.values());
    }

    // getters, setters, toString
}

Animalクラスを変更する必要はまったくありません。以下のプログラム:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
ZooAnimals zooAnimals = mapper.readValue(XML, ZooAnimals.class);
System.out.println(zooAnimals);

プリント:

ZooAnimals{size='2', animalList=[Animal{name='elephant', size='huge'}, Animal{name='termite', size='verysmall'}]}
于 2014-09-06T11:24:53.537 に答える