Java 使用Jackson无字符串参数构造函数/工厂方法从字符串值反序列化的XML映射(';比利时华夫饼';)
出于学习目的,我尝试将xml文件映射到pojo。我的xml如下所示:Java 使用Jackson无字符串参数构造函数/工厂方法从字符串值反序列化的XML映射(';比利时华夫饼';),java,xml,jackson,Java,Xml,Jackson,出于学习目的,我尝试将xml文件映射到pojo。我的xml如下所示: <breakfast_menu> <food> <name>Belgian Waffles</name> <price>$5.95</price> <description> Two of our famous Belgian Waffles with plenty of real maple
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>
Two of our famous Belgian Waffles with plenty of real maple syrup
</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>
Light Belgian waffles covered with strawberries and whipped cream
</description>
<calories>900</calories>
</food>
</breakfast_menu>
主要功能:
public static void main(String[] args) {
File file = new File("X:\\food.xml");
XmlMapper xmlMapper = new XmlMapper();
try {
String xml = inputStreamToString(new FileInputStream(file));
BreakfestFood value = xmlMapper.readValue(xml, BreakfestFood.class);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
当我运行此代码时,我得到如下堆栈:
用于从字符串值(“比利时华夫格”)反序列化的字符串参数构造函数/工厂方法。所以它似乎无法映射食物的名称和价值。有人知道怎么回事吗?您的映射不正确。
为了检查错误,我建议您序列化一个简单的对象
BreakfestFood bf = new BreakfestFood();
Food f1 = new Food();
f1.setName("f1Name");
f1.setCalories(20);
f1.setDescription("desc");
f1.setPrice(11.1);
bf.setFood(List.of(f1));
System.out.println(xmlMapper.writeValueAsString(bf));
Output:
<breakfast_menu>
<food>
<food>
<price>11.1</price>
<description>desc</description>
<calories>20</calories>
<name>f1Name</name>
</food>
</food>
</breakfast_menu>
BreakfestFood bf=新的BreakfestFood();
食品f1=新食品();
f1.设定名称(“设定名称”);
f1.总热量(20);
f1.设置说明(“描述”);
f1.设定价格(11.1);
bf.setFood(f1列表);
System.out.println(xmlMapper.writeValueAsString(bf));
输出:
11.1
描述
20
f1Name
如您所见,您为列表获得了一个额外的包装器。
要摆脱它,请使用:
@JacksonXmlRootElement(localName = "breakfast_menu")
public class BreakfestFood {
// Use this to change element name:
// @JacksonXmlProperty(localName = "food")
@JacksonXmlElementWrapper(useWrapping = false)
private List<Food> food;
// getters and setters
}
@JacksonXmlRootElement(localName=“早餐菜单”)
公共类食品{
//使用此选项更改元素名称:
//@JacksonXmlProperty(localName=“food”)
@JacksonXmlElementWrapper(useWrapping=false)
私人食品清单;
//接球手和接球手
}
除此之外:
- 如果你有公共获取者,食物中的注释是多余的
- 价格标签中的值不是双倍的。您需要调整映射以解析货币值。定制
和@JsonSerialize
是解决这一问题的一种方法@JsonSerialize
- 一般来说,将价格存储为双倍是一个糟糕的主意
BreakfestFood bf = new BreakfestFood();
Food f1 = new Food();
f1.setName("f1Name");
f1.setCalories(20);
f1.setDescription("desc");
f1.setPrice(11.1);
bf.setFood(List.of(f1));
System.out.println(xmlMapper.writeValueAsString(bf));
Output:
<breakfast_menu>
<food>
<food>
<price>11.1</price>
<description>desc</description>
<calories>20</calories>
<name>f1Name</name>
</food>
</food>
</breakfast_menu>
@JacksonXmlRootElement(localName = "breakfast_menu")
public class BreakfestFood {
// Use this to change element name:
// @JacksonXmlProperty(localName = "food")
@JacksonXmlElementWrapper(useWrapping = false)
private List<Food> food;
// getters and setters
}