java - RestTemplate XML 在具有属性的空标记上反序列化 null
问题描述
我有以下响应,当值在属性中并且my
标签除了属性之外没有值(也是级别并且我可以有多个值)
<main>
<level id="1">
<my id="111" amount="100000.00"/>
</level>
<level id="2">
<my id="121" amount="5000.00"/>
</level>
<level id="3">
<my id="122" amount="500.00"/>
</level>
</main>
尝试反序列化时my
为空
ResponseEntity<RequestVO> jackpotFeederResponse = restTemplate.exchange(uriBuilder.build(), HttpMethod.GET,
HttpEntity.EMPTY, RequestVO.class);
我尝试添加不同DeserializationFeature
的,但失败了
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, true);
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
converter.setObjectMapper(objectMapper);
restTemplate.getMessageConverters().add(converter);
我的 POJO:
@XmlRootElement(name = "main", namespace = "")
@Data
public class RequestVO implements Serializable {
private static final long serialVersionUID = -1382015668147149795L;
@JacksonXmlProperty(localName = "level")
ArrayList<LevelVO> levelList;
}
@XmlRootElement(name = "level", namespace = "")
@Data
public class LevelVO implements Serializable {
private static final long serialVersionUID = -1382015668147149795L;
@JacksonXmlProperty(localName = "id", isAttribute = true)
String id;
@JacksonXmlProperty(localName = "my")
ArrayList<MyVO> myList;
@XmlRootElement(name = "my", namespace = "")
@Data
public class MyVO implements Serializable {
private static final long serialVersionUID = -1382015668147149795L;
@JacksonXmlProperty(localName = "id", isAttribute = true)
String id;
解决方案
首先,您应该@JacksonXmlElementWrapper(useWrapping = false)
在您的集合类型上使用。接下来尽量不要将 JAXB 注释与杰克逊注释混合。因此只需使用@JacksonXmlRootElement 而不是@XmlRootElement。
您的 XML POJO 应如下所示:
@JacksonXmlRootElement(localName = "main")
@Data
public class RequestVO implements Serializable {
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "level")
ArrayList<LevelVO> levelList;
}
@JacksonXmlRootElement(localName = "level")
@Data
public class LevelVO implements Serializable {
@JacksonXmlProperty(localName = "id", isAttribute = true)
String id;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "my")
ArrayList<MyVO> myList;
}
@JacksonXmlRootElement(localName = "my")
@Data
public class MyVO implements Serializable {
@JacksonXmlProperty(localName = "id", isAttribute = true)
String id;
@JacksonXmlProperty(localName = "amount", isAttribute = true)
String amount;
}
如果你真的想坚持使用 @XmlRootElement 注解。可能您还必须将 JaxbAnnotationModule 注册到 Jacksons XmlMapper:
JaxbAnnotationModule module = new JaxbAnnotationModule();
xmlMapper.registerModule(module);
推荐阅读
- python - 如果并行调用,Redis Pipeline 需要时间
- vue.js - vue-croppa:获取原始图像并用作另一个 Croppa 组件的初始图像
- swift - 自定义 UITextField 类中的 draw(_ rect: CGRect) 不要在 ios 14 上调用
- java - 将目标 sdk 升级到 30 时初始化 youtube 播放器时出错
- javascript - Laravel HTML Select输入在数据库中保存不同的值?
- python - 缩短字符串/数组索引
- ruby-on-rails - 如何在rails中为数组类编写方法
- django - 如何修复heroku中的应用程序响应错误?
- python - 如何使用 Pytest 断言多个值
- javafx - Gluon Scene Builder:来自源代码的自定义控件