无String-argument构造函数/工厂方法,当它是一个Integer时,从String值反序列化

时间:2017-07-31 21:51:32

标签: java jackson xmlmapper

我试图将以下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;
}
}

我的mapper依赖项如下:

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')

at [Source:out / test / resources / test.xml; line:4,column:16](通过参考链:service.Foo [&#34; dean&#34;] - &gt; service.Dean [&#34; bar&#34;] - &gt; java.util.ArrayList [0])

从读取异常看起来,映射器将值28视为字符串而不是整数,但如果我将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));
}

我想说Mapper应该从构造函数参数类型推断出类型,并尝试使用字符串值实例化该对象,并在引擎盖下执行类似Integer.valueOf(&#34; 28&#34;)

1 个答案:

答案 0 :(得分:2)

添加到POJO空构造函数以及所有字段。 还请尝试以下方法:

JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
XmlMapper xmlMapper = new XmlMapper(module);