2
我想deserialise以下XML到对象:没有字符串参数的构造函数/ factory方法字符串值反序列化时,它是一个整数
<?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')
在[来源抛出:出/测试/资源/的test.xml; line:4,column:16](通过引用链:service.Foo [“dean”] - > service.Dean [“bar”] - > 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));
}
我要说的是,映射应推断从构造函数参数类型的类型,并尝试实例化对象与字符串值,并在引擎盖下做类似Integer.valueOf(“28”)
它适用于从Bar构造函数中删除参数。 – Andreas
但这意味着你将需要使类不可变,这是不希望的 –