【问题标题】:How do I deserialize an array with indexes using jackson如何使用杰克逊反序列化带有索引的数组
【发布时间】:2014-10-30 22:27:31
【问题描述】:

我正在引用一个返回数组格式的网络服务:

{
    "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;
...
}

有没有办法注释这个类,这样杰克逊就可以反序列化上面的文本而不必编写自定义代码?顺便说一句,保持排序不是必需的。

【问题讨论】:

  • 我对此表示怀疑。 Web 服务没有返回 json 数组(请参阅 w3schools.com/json/json_syntax.asp 等),因此您可能必须编写一些自定义序列化才能将其放入列表中。

标签: java arrays json jackson indexed


【解决方案1】:

你必须使用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'}]}

【讨论】:

  • 完美运行。感谢您提供清晰简洁的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多