2017-07-31 27 views
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”)

+0

它适用于从Bar构造函数中删除参数。 – Andreas

+0

但这意味着你将需要使类不可变,这是不希望的 –

回答

1

添加到POJO空构造函数以及所有字段。 另请尝试以下操作:

JacksonXmlModule module = new JacksonXmlModule(); 
module.setDefaultUseWrapper(false); 
XmlMapper xmlMapper = new XmlMapper(module); 
相关问题