java - 使用杰克逊没有字符串参数构造函数/工厂方法的 XML 映射来反序列化字符串值(“比利时华夫饼”)
问题描述
出于学习目的,我正在尝试将 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 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>
Breakfes实体类
@JacksonXmlRootElement(localName = "breakfast_menu")
public class BreakfestFood {
private List<Food> food;
public BreakfestFood() {}
public List<Food> getFood() {
return food;
}
public void setFood(List<Food> food) {
this.food = food;
}
}
食品实体类
@JacksonXmlRootElement(localName = "food")
public class Food {
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlProperty
private double price;
@JacksonXmlProperty
private String description;
@JacksonXmlProperty
private int calories;
主要功能:
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();
}
}
当我运行这段代码时,我得到这样的堆栈:String-argument constructor/factory method to deserialize from String value ('Belgian Waffles')。所以它似乎无法映射食物的名称值。有人知道出了什么问题吗?
解决方案
您的映射不正确。为了检查有什么问题,我鼓励您序列化一个简单的对象。
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
}
最重要的是:
- 如果你有公共吸气剂,Food 中的注释是多余的
- 价格标签中的值不是双倍的。您需要调整映射以解析货币值。定制是解决这个问题的一个想法
@JsonSerialize
。@JsonDeserialize
- 更一般地说,将价格存储为双倍是一个糟糕的主意。
推荐阅读
- java - 高并发 Apache HTTP Server SSL 问题
- javascript - 从所有类都相同的特定类中获取文本-Selenium-Javascript
- python - Python:查找方法以匹配来自两个数据帧的相似但不相同的名称
- microsoft-teams - Azure Bot Framework - MS Team 集成 - 语音功能
- google-apps-script - Google 表格插件侧边栏点击事件不适用于某些用户
- sql - 根据另一列中的更改创建带有时间戳的最后修改列
- google-cloud-platform - 谷歌云平台 - 项目消失了
- sql-server - 将数据从一个表拆分到另一个表
- request - 浏览器 Axios 获取文件但响应未定义
- vmware - 如何从 2 个物理 HDD 在 esxi 6.5 中创建虚拟存储?