如何使用 Dapr 的 Java SDK 处理 Java 8 日期/时间序列化

问题描述 投票:0回答:1

我目前正在使用 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 一起使用?任何帮助将不胜感激!

java serialization jackson dapr
1个回答
0
投票

通过创建自定义序列化器类并将 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();

这解决了问题!

© www.soinside.com 2019 - 2024. All rights reserved.