我目前正在使用 Dapr 的 Java SDK 版本 1.9.0 开发 Spring Boot 应用程序。当我尝试发布包含 java.time.Instant 对象的事件时,遇到序列化问题。
我有这些与 DAPR 相关的依赖项:
implementation 'io.dapr:dapr-sdk:1.9.0'
implementation 'io.dapr:dapr-sdk-springboot:1.9.0'
implementation 'io.dapr:dapr-sdk-actors:1.9.0'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.16.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
堆栈跟踪指向 Dapr 的内部 ObjectSerializer:
io.dapr.exceptions.DaprException: UNKNOWN: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: ...)]
我已经将 jackson-datatype-jsr310 依赖项添加到我的项目中,并使用我的应用程序的 ObjectMapper 注册了该模块。然而,Dapr 的 ObjectSerializer 似乎正在使用不同的 ObjectMapper 实例。
这是我的代码的相关部分:
// ... other code ...
Job job = new Job();
job.setQueued(Instant.now());
daprClient.publishEvent("myTopic", job).block();
// ... other code ..
.
有没有办法自定义Dapr的ObjectSerializer使用的ObjectMapper?或者是否有另一种解决方法可以将 java.time.Instant 与 Dapr 的 Java SDK 一起使用?任何帮助将不胜感激!
通过创建自定义序列化器类并将 javaTimeModule() 包含到 ObjectMapper 实例中解决了此问题。
public class JacksonDaprObjectSerializer implements DaprObjectSerializer {
private final ObjectMapper objectMapper;
public JacksonDaprObjectSerializer(ObjectMapper objectMapper) {
objectMapper.registerModule(new JavaTimeModule());
this.objectMapper = objectMapper;
}
@Override
public byte[] serialize(Object o) {
try {
return objectMapper.writeValueAsBytes(o);
} catch (IOException e) {
throw new DaprException(e);
}
}
@Override
public <T> T deserialize(byte[] data, TypeRef<T> type) throws IOException {
try {
JavaType javaType = objectMapper.getTypeFactory().constructType(type.getType());
return objectMapper.readValue(data, javaType);
} catch (IOException e) {
throw new DaprException(e);
}
}
@Override
public String getContentType() {
return "application/json";
}
}
添加了此自定义序列化器用于构建 dapr 客户端实例:
DaprObjectSerializer serializer = new JacksonDaprObjectSerializer(new ObjectMapper());
DaprClient client = (new DaprClientBuilder())
.withObjectSerializer(serializer) // for request/response objects.
.withStateSerializer(serializer) // for state objects.
.build();
这解决了问题!