英文:
How can I model a generic Jackson POJO with a field that is changing the name?
问题
我与一组API进行交互,它们都返回类似的响应:
{
"common1": ...,
"common2": ...,
"common3": ...,
"someList": [
//这里是多态对象
]
}
目前,我为每个响应都有一个单独的POJO。但是我希望将其因子化为一个通用对象,因为我总是对这样的对象执行相同的操作,这导致了很多代码重复。
最初,我想创建一个类似的Jackson类:
public class CommonClass<T> {
@JsonProperty("common1")
private final CommonType1 common1;
@JsonProperty("common2")
private final CommonType2 common2;
@JsonProperty("common3")
private final CommonType3 common3;
@JsonProperty("someList")
private final List<T> someList;
//这里放构造函数和getter方法
}
这样会很好运行,但有一个问题:someList
的Json名称也会变化。有时它是someListA
,有时它是someListB
... 基本上它的名称会根据它包含的类型而变化。
这使得按照这种方法(至少我认为是这样)变得不可能,因为我无法动态更改我的POJO中JsonProperty()
注解的值。
我知道我可以创建一个基类,然后创建多个该类的扩展,每个扩展都有不同名称的列表,但这不是我的理想解决方案,因为我将无法拥有一个通用的getter方法来处理元素,而无需向我正在处理的POJO的具体类型进行向下转换。
对于这个问题,你有任何想法/建议/方法吗?
英文:
I interact with a set of APIs that all return a similar response:
{
"common1": ...,
"common2": ...,
"common3": ...,
"someList": [
//polymorph objects here
]
}
Currently, I have a separate POJO for each of these responses. However I would like to factorize this in a common object since I always perform the same actions with such object and that makes a lot of code duplication.
Initially, I had thought to create a similar Jackson class:
public class CommonClass<T> {
@JsonProperty("common1")
private final CommonType1 common1;
@JsonProperty("common2")
private final CommonType2 common2;
@JsonProperty("common3")
private final CommonType3 common3;
@JsonProperty("someList")
private final List<T> someList;
//constructor and getters here
}
This would work fine, except for an issue: the Json name of someList
changes as well. Sometimes it's someListA
, sometimes it's someListB
... basically it changes depending on the type it contains.
That makes it impossible to follow this approach (at least I think) since I can't dynamically change the value of the JsonProperty()
annotations in my POJO.
I know that I could create a base class and then multiple extensions of such class, each one with a different list (differently named), but that wouldn't be my ideal solution because I wouldn't be able to have a common getter to process the elements without downcasting to the concrete type of POJO that I'm handling.
Do you have any idea/suggestion/approach for such problem?
答案1
得分: 1
如果名称选项列表不太长,您可以使用JsonAlias。
> 注解可用于定义一个或多个属性的替代名称,在反序列化期间作为官方名称的替代名称被接受。在POJO内省期间,别名信息也会被公开,但在序列化期间没有任何效果,始终使用主要名称。
示例:
public class CommonClass<T> {
@JsonProperty("common1")
private final CommonType1 common1;
@JsonProperty("common2")
private final CommonType2 common2;
@JsonProperty("common3")
private final CommonType3 common3;
@JsonProperty("someList")//official name, used during serialization
@JsonAlias({"someListA", "someListB"})//aliases used during deserialization, if the official name was not found
private final List<T> someList;
}
英文:
If the list of options for the name is not too long, you can use JsonAlias.
> Annotation that can be used to define one or more alternative names for a property, accepted during deserialization as alternative to the official name. Alias information is also exposed during POJO introspection, but has no effect during serialization where primary name is always used.
Example:
public class CommonClass<T> {
@JsonProperty("common1")
private final CommonType1 common1;
@JsonProperty("common2")
private final CommonType2 common2;
@JsonProperty("common3")
private final CommonType3 common3;
@JsonProperty("someList")//official name, used during serialization
@JsonAlias({"someListA", "someListB"})//aliases used during deserialization, if the official name was not found
private final List<T> someList;
}
答案2
得分: 0
最简单的方法是将其反序列化为 Map<String, Object>
,然后以相同的方式处理映射,只是在检索 someList*
属性时,不是查找特定的键,如 someListA
或 SomeListB
,而是搜索以 "someList"
前缀开头的键。
英文:
The simplest way is to deserialize it as a Map<String, Object>
and than treat your map the same way except when retrieving someList* property instead of looking for a particular key such as someListA
or SomeListB
just search for the key that starts with "someList"
prefix
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论