使用没有 JsonSubTypes 的 jackson 将接口反序列化为特定类型
Deserialize interface to specific type with jackson without JsonSubTypes
我有一个项目 A,我有一个这样的界面:
interface MyInterface extends Serializable { }
在另一个项目 B 中,我有一个 class 实现了该接口:
@Data
class MyClass implements MyInterface {
private String someProp;
}
现在我想告诉jackson,我想将MyInterface
的所有出现反序列化为MyClass
。我知道通常可以使用 JsonSubTypes
但在这种情况下项目 A 不知道项目 B.
有没有办法获取类型的默认反序列化器?然后我可以做这样的事情:
SimpleModule module = new SimpleModule();
module.addDeserializer(MyInterface.class, DefaultDeserializerForMyClass);
我知道我可以编写完全相同的自定义反序列化器,但是有更简单的方法吗?
您可以在 MyClass
上添加 @JsonDeserialize
并使用 ObjectMapper.addMixIn()
和 MyInterface
作为目标。
public ObjectMapper addMixIn(Class target,
Class mixinSource)
Method to use for adding mix-in annotations to use for augmenting
specified class or interface. All annotations from mixinSource are
taken to override annotations that target (or its supertypes) has.
target - Class (or interface) whose annotations to effectively override
mixinSource - Class (or interface) whose annotations are to be "added" to target's annotations, overriding as necessary
例如:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(as = MyClass.class)
class MyClass implements MyInterface
{
private String someProp;
/* getters and setters */
}
@Bean
public ObjectMapper objectMapper()
{
ObjectMapper om = new ObjectMapper();
om.addMixIn(MyInterface.class, MyClass.class);
return om;
}
@PostMapping
public String foo(@RequestBody MyInterface bar)
{
if (bar instanceof MyClass) {
MyClass baz = (MyClass)bar;
System.out.println(baz.getSomeProp());
return "world"
}
return "goodbye"
}
$ curl -X POST -d '{"someProp": "hello"}' -H "content-type: application/json" localhost:8080
world
并且服务器正确打印:
hello
我有一个项目 A,我有一个这样的界面:
interface MyInterface extends Serializable { }
在另一个项目 B 中,我有一个 class 实现了该接口:
@Data
class MyClass implements MyInterface {
private String someProp;
}
现在我想告诉jackson,我想将MyInterface
的所有出现反序列化为MyClass
。我知道通常可以使用 JsonSubTypes
但在这种情况下项目 A 不知道项目 B.
有没有办法获取类型的默认反序列化器?然后我可以做这样的事情:
SimpleModule module = new SimpleModule();
module.addDeserializer(MyInterface.class, DefaultDeserializerForMyClass);
我知道我可以编写完全相同的自定义反序列化器,但是有更简单的方法吗?
您可以在 MyClass
上添加 @JsonDeserialize
并使用 ObjectMapper.addMixIn()
和 MyInterface
作为目标。
public ObjectMapper addMixIn(Class target, Class mixinSource)
Method to use for adding mix-in annotations to use for augmenting specified class or interface. All annotations from mixinSource are taken to override annotations that target (or its supertypes) has.
target - Class (or interface) whose annotations to effectively override mixinSource - Class (or interface) whose annotations are to be "added" to target's annotations, overriding as necessary
例如:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@JsonDeserialize(as = MyClass.class)
class MyClass implements MyInterface
{
private String someProp;
/* getters and setters */
}
@Bean
public ObjectMapper objectMapper()
{
ObjectMapper om = new ObjectMapper();
om.addMixIn(MyInterface.class, MyClass.class);
return om;
}
@PostMapping
public String foo(@RequestBody MyInterface bar)
{
if (bar instanceof MyClass) {
MyClass baz = (MyClass)bar;
System.out.println(baz.getSomeProp());
return "world"
}
return "goodbye"
}
$ curl -X POST -d '{"someProp": "hello"}' -H "content-type: application/json" localhost:8080
world
并且服务器正确打印:
hello