是否有现有的 Quarkus 函数可以从 JSON 字符串反序列化 CloudEvent?

Is there an existing Quarkus function to deserialise a CloudEvent from a JSON String?

提问人:Robin Hugues 提问时间:11/13/2023 最后编辑:Robin Hugues 更新时间:11/21/2023 访问量:65

问:

我目前正在使用 Quarkus,在想要将通过 WebSocket 接收的 JSON 字符串消息反序列化为 CloudEvent 时遇到了一个问题。

使用 Quarkus ObjectMapper 不起作用,因为 Quarkus CloudEvent 堆栈使用私有类和构建器来实例化 CloudEvents。然后我不能使用以下内容:

public CloudEvent<?> createCloudEvent(String message) throws JsonProcessingException {
    return objectMapper.readValue(message, SimpleCloudEvent.class);
}

我试图用这个来回避这个问题:

public CloudEvent<?> createCloudEvent(String message) throws JsonProcessingException {
    return objectMapper.readValue(message, CloudEventBuilder.create().build(null).getClass());
}

但这一次,映射器无法将不属于 CloudEvent 规范的标头反序列化到 extensions 字段中,因为 SimpleCloudEvent 构造函数没有针对每个可能的标头的任何显式字段。

尽管如此,在另一个项目中使用 Funqy Knative,我仍然假设 Quarkus ObjectMapper 可以将 String 或 JSON 对象反序列化为 CloudEvents。以下代码片段可以解释为什么我认为:

@Funq
public void receiveCloudEvent(CloudEvent<String> cloudEvent) {
    //do something with the received CE
}

在这里,发送到我的应用程序的是一个 HTTP 请求,它最终是一个 JSON 对象。因此,无论是 Quarkus 框架还是 Funqy Knative 框架都能够将其转换为有效的 SimpleCloudEvent,甚至在扩展映射中包含不属于 CloudEvent 规范的标头。

有谁知道框架在做什么类/函数以及它是否可用?

或者我真的应该只做一个自定义解串器吗?

多谢!

反序列化 Quarkus ObjectMapper CloudEvents

评论


答:

0赞 Serkan 11/17/2023 #1

这与Quarkus无关。

你需要看看杰克逊。如果你在谷歌上搜索:Jackson 和 builder 模式,你会发现关于这个问题的足够信息。

或者,如果 CloudEvent 是作为第三方库提供的,您可能还需要查看 Jackson mixins。

1赞 Matej Vašek 11/21/2023 #2

Knative Funq 确实应该反序列化 JSON 值(Object,String,Number,Boolean,Array,Null)。

您的示例:

@Funq
public void receiveCloudEvent(CloudEvent<String> cloudEvent) {
    //do something with the received CE
}

此函数需要 JSON 字符串(而不是 Object)作为数据。 通过以下方式进行有效调用的示例:cURL

curl "http://localhost:8080" \    
  -H "Content-Type:application/json" \
  -H "Ce-Id:42" \
  -H "Ce-Source:sample-source" \
  -H "Ce-Type:sample-input" \
  -H "Ce-Specversion:1.0" \
  -d '"json string"'

请注意数据中的引号。

JSON 对象的示例可以是:

public class Person {
    public String name;
    public int age;
}

public void receiveCloudEvent(CloudEvent<Person> cloudEvent) {
    //do something with the received CE
}

cURL调用:

curl "http://localhost:8080" \    
  -H "Content-Type:application/json" \
  -H "Ce-Id:42" \
  -H "Ce-Source:sample-source" \
  -H "Ce-Type:sample-input" \
  -H "Ce-Specversion:1.0" \
  -d '{"name": "John", "age": 42 }'

最后,当您想自己使用以下命令进行反序列化时,还有一个逃生舱口:byte[]

public void receiveCloudEvent(CloudEvent<byte[]> cloudEvent) {
    // deserialize data from byte array
}

Funq 序列化/反序列化是私有的。如果你想要更开放的东西,看看 https://github.com/cloudevents/sdk-java