问题描述
我有以下三个应用程序:
I have the following three applications:
- 业务逻辑(Spring Cloud功能)
- 接口 IDemoEntity
- Business logic (Spring Cloud Function)
- An interface IDemoEntity
- 特定于AWS的处理程序
- IDemoEntity 的一种实现,带有DynamoDB特定的注释
- 该项目基于Spring Boot
- AWS-specific handler
- One implementation of IDemoEntity, with DynamoDB-specific annotations
- The project is based on Spring Boot
- IDemoEntity 的一个实现,带有CosmosDB批注
- 天蓝色特定的处理程序
- One implementation of IDemoEntity, with CosmosDB annotation
- Azure-specific handler
项目1的类如下:
public interface IDemoEntity {
String getName();
void setName(String name);
}
@Component
public class StoreFunction implements Consumer<Message<IDemoEntity>> {
@Override
public void accept(Message<IDemoEntity> t) {
System.out.println("Stored entity " + t.getPayload().getName());
return;
}
}
对于项目2,IDemoEntity的实现如下所示:
For project 2, the implementation of IDemoEntity looks like this:
@DynamoDBTable(tableName = "DemoEntity")
public class DynamoDemoEntity implements IDemoEntity {
private String name;
@Override
@DynamoDBHashKey
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
对于项目3, IDemoEntity 的实现与 DynamoDemoEntity 相似,但带有CosmosDB批注.
For project 3, the implementation of IDemoEntity would look similar to DynamoDemoEntity, but with CosmosDB annotations.
结构可能看起来有点复杂,但是其构想如下:
The structure might look a bit complicated, but the idea is the following:
- 一次实施业务逻辑和数据模型(在项目1中)(利用Spring Cloud Function)
- 仅针对每个平台实施一个包装项目(我从项目2中的AWS Lambda开始,但针对Azure的项目3看起来很相似),以及特定于平台的内容(例如实体实现,需要特定于DB的东西)注释)
- 使用项目1作为依赖项编译特定于平台的项目(例如,AWS Lambda的项目2)
我已经尝试过了,安装程序基本上可以正常工作了.但是,有一个大问题:
I've tried it, and the setup works basically.However, there is one big problem:
调用上面的 StoreFunction 时,Jackson抛出以下异常:
When calling the StoreFunction above, Jackson throws the following exception:
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `de.margul.awstutorials.springcloudfunction.logic.IDemoEntity` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (String)"{"name": "Detlef"}"; line: 1, column: 1]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1452)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1028)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3004)
at de.margul.awstutorials.springcloudfunction.aws.handler.RestSpringBootApiGatewayRequestHandler.deserializeBody(RestSpringBootApiGatewayRequestHandler.java:57)
... 3 more
这是有道理的,因为杰克逊不知道,如果IDemoEntity
它将对接收到的JSON反序列化到哪个实现.
That makes sense, because Jackson does not know, to which implementation if IDemoEntity
it shall deserialize the received JSON.
现在最简单的方法是将@JsonDeserialize(as = DynamoDemoEntity.class)
放置在IDemoEntity
上.
The easiest way now would be to place a @JsonDeserialize(as = DynamoDemoEntity.class)
on IDemoEntity
.
但是,这将破坏我的完整结构:项目1将不包含任何信息,它是与哪个平台特定的项目一起编译的.
However, that would break my complete structure: Project 1 shall have no information, which platform-specific project it is compiled with.
有什么想法,我如何提供自定义解串器(例如Spring bean),而又不对项目1进行平台特定的修改?
Any ideas, how I could provide a custom deserializer (e. g. as Spring bean), but without making platform-specific modifications in project 1?
推荐答案
首先,您需要创建自定义DynamoDemoEntityDeserializer
,如下所示:
Firstly, you need to create your custom DynamoDemoEntityDeserializer
like below:
class DynamoDemoEntityDeserializer extends JsonDeserializer<DynamoDemoEntity> {
@Override
public DynamoDemoEntity deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
// return DynamoDemoEntity instance;
}
}
然后您可以创建com.fasterxml.jackson.databind.Module
的bean,如下所示:
Then you can create bean of com.fasterxml.jackson.databind.Module
like below:
@Bean
public Module dynamoDemoEntityDeserializer() {
SimpleModule module = new SimpleModule();
module.addDeserializer(IDemoEntity.class, new DynamoDemoEntityDeserializer());
return module;
}
这篇关于如何使用Jackson和Spring Boot提供自定义解串器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!