3

次のxmlをオブジェクトに逆シリアル化しようとしています:

<?xml version="1.0" encoding="iso-8859-1" ?>
   <foo>
     <dean>
      <bar>28</bar>
      <bar>31</bar>
    </dean>
  </foo>

私のクラスは次のとおりです

public class Foo {

private final Dean dean;

public Foo(@JacksonXmlProperty(localName = "dean") final Dean dean) {
    this.dean = dean;
}

public Dean getDean() {
    return dean;
}
}

public class Dean {

@JacksonXmlElementWrapper(useWrapping = false)
private final List<Bar> bar;

public Dean(@JacksonXmlProperty(localName = "bar") final List<Bar> bar) {
    this.bar = bar;
}

public List<Bar> getBar() {
    return bar;
}
}

public class Bar {

@JacksonXmlText
private Integer value;

public Bar(@JacksonXmlProperty(localName = " ") Integer value) {
    this.value = value;
}


public Integer getValue() {
    return value;
}
}

私のマッパーの依存関係は次のとおりです。

gradle
ext {
jacksonVersion = "2.8.9"

}

compile(group: "com.fasterxml.jackson.dataformat", name: "jackson-dataformat-
xml", version: "$jacksonVersion")
compile(group: "com.fasterxml.jackson.datatype", name: "jackson-datatype-
jsr310", version: "$jacksonVersion")enter code here

これは、xmlMapper によって例外がスローされた失敗したテストです。

@Test
public void shouldParseAndCreateObject() throws Exception {
    final JacksonXmlModule jacksonXmlModule = new JacksonXmlModule();
     XmlMapper xmlMapper = (XmlMapper) new XmlMapper(jacksonXmlModule)
            .disable(FAIL_ON_UNKNOWN_PROPERTIES, FAIL_ON_IGNORED_PROPERTIES);
    Foo foo = xmlMapper.readValue("<?xml version=\"1.0\" encoding=\"iso-8859-
1\" ?>\n" +
            "<foo>\n" +
            "    <dean>\n" +
            "        <bar>28</bar>\n" +
            "        <bar>31</bar>\n" +
            "    </dean>\n" +
            "</foo>", Foo.class);
    assertThat(foo.getDean().getBar().get(0).getValue(), is(28));
}

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of Bar: no String-argument constructor/factory method to deserialize from String value ('28')

[ソース: out/test/resources/test.xml; 行: 4、列: 16] (参照チェーン経由: service.Foo["dean"]->service.Dean["bar"]->java.util.ArrayList[0])

例外を読むと、マッパーが値 28 を整数ではなく文字列として扱っているように見えますが、Bar クラスを次のように変更し、要素 bar の属性を生の xml に追加すると、同じテストに合格します。

public class Bar {

private String test;

@JacksonXmlText
private Integer value;

public Bar(@JacksonXmlProperty(localName = "test", isAttribute = true) String 
test, @JacksonXmlProperty(localName = " ") Integer value) {
    this.test = test;
    this.value = value;
}

public String getTest() {
    return test;
}

public Integer getValue() {
    return value;
}

<?xml version="1.0" encoding="iso-8859-1" ?>
<foo>
<dean>
    <bar test="haha1">28</bar>
    <bar test="haha2">31</bar>
</dean>
</foo>

@Test
public void shouldParseAndCreateObject() throws Exception {
    final JacksonXmlModule jacksonXmlModule = new JacksonXmlModule();
     XmlMapper xmlMapper = (XmlMapper) new XmlMapper(jacksonXmlModule)
            .disable(FAIL_ON_UNKNOWN_PROPERTIES, FAIL_ON_IGNORED_PROPERTIES);
    Foo foo = xmlMapper.readValue("<?xml version=\"1.0\" encoding=\"iso-8859-
1\" ?>\n" +
            "<foo>\n" +
            "    <dean>\n" +
            "        <bar test=\"haha1\">28</bar>\n" +
            "        <bar test=\"haha2\">31</bar>\n" +
            "    </dean>\n" +
            "</foo>" +
            "</foo>", Foo.class);
    assertThat(foo.getDean().getBar().get(0).getValue(), is(28));
}

マッパーはコンストラクターのパラメーターの型から型を推測し、そのオブジェクトを文字列値でインスタンス化し、フードの下で Integer.valueOf("28") のようなことを行う必要があると思います

4

1 に答える 1