Jackson XML 反序列化,InvalidDefinitionException:属性“时间”的 getter 定义冲突
Posted
技术标签:
【中文标题】Jackson XML 反序列化,InvalidDefinitionException:属性“时间”的 getter 定义冲突【英文标题】:Jackson XML deserialization, InvalidDefinitionException: Conflicting getter definitions for property "time" 【发布时间】:2021-10-04 08:22:54 【问题描述】:我有一个这样的 DTO:
package ...;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.*;
import lombok.experimental.FieldDefaults;
import java.time.LocalDateTime;
import java.util.List;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@JacksonXmlRootElement(localName = "root")
public class RootDto
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime time;
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JacksonXmlElementWrapper(localName = "times")
@JacksonXmlProperty(localName = "time")
List<InternalTimeDto> times;
...
package ...;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import lombok.*;
import lombok.experimental.FieldDefaults;
import java.time.LocalDateTime;
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class InternalTimeDto
@JacksonXmlProperty(isAttribute = true)
Long id;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime time;
据我了解,问题在于time
字段和times
字段的元素具有相同的名称。有没有办法在不将time
重命名为其他名称的情况下解决冲突?理论上应该完全没有冲突,因为time
字段和列表项处于不同的级别。
XML 示例:
<root>
<time>2020-11-18 12:34</time>
<times>
<time id="5">2020-11-18 10:00</time>
<time id="6">2020-11-17 15:30</time>
</times>
...
</root>
我找到了几个答案,但是当两个具有相同名称的不同对象处于同一级别时,它们解决了问题。
也使用JSON:
"time": "2020-11-18 12:34",
"times": [
"id": 5,
"time": "2020-11-18 10:00"
,
"id": 6,
"time": "2020-11-17 15:30"
],
...
【问题讨论】:
【参考方案1】:解决由于多个定义的属性 time
保留您的 xml 格式而引起的冲突的一种方法是创建一个包装您的 List<InternalTimeDto>
次的 Times
类:
public class Times
@JacksonXmlProperty(localName = "time")
@JacksonXmlElementWrapper(useWrapping = false)
List<InternalTimeDto> times;
所以你的RootDto
类可以这样重写:
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
@FieldDefaults(level = AccessLevel.PRIVATE)
@JacksonXmlRootElement(localName = "root")
public class RootDto
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime time;
@JsonInclude(value = JsonInclude.Include.NON_NULL)
private Times times; //<-- times field instead of List<InternalTimeDto> times
您的InternalTimeDto
类需要JacksonXmlText
注释用于time
字段:
@Getter
@Setter
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class InternalTimeDto
@JacksonXmlProperty(isAttribute = true)
Long id;
@JacksonXmlText
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
LocalDateTime time;
【讨论】:
谢谢,现在这对 XML 很好。不幸的是,为了简单起见,我没有提到也使用 JSON。我已经更新了问题。 @YaroslavTarasenko 欢迎您。使用我的类在RootDto
的json 案例中,将Times 类替换为List<InternalTimeDto> times
,否则如果你想对xml 和json 使用相同的代码,唯一的选择是为Times
类编写一个自定义反序列化器。
是的,在我看来,自定义反序列化器是唯一的解决方案。谢谢。以上是关于Jackson XML 反序列化,InvalidDefinitionException:属性“时间”的 getter 定义冲突的主要内容,如果未能解决你的问题,请参考以下文章