在 Vertx 中通过事件总线发送 collection of objects 的最佳方法是什么?
What is the best way to send a collection of objects over the Event Bus in Vertx?
我有一个在给定端点处理 HTTP 请求的处理程序。处理程序通过事件总线向 Verticle 发送消息,该事件总线进行一些外部分页 REST 调用,聚合结果,然后 returns 将结果返回给处理程序。分页 REST 调用的结果表示为自定义列表 object。如果我只是尝试发送 List
本身,Vertx 会抛出一个异常,抱怨它找不到 java.util.ArrayList
.
的编解码器
我正在尝试找到 "best"——意思是最简单、最有效、最 readable/maintainable——在 Vertx 中发送这些 object 列表的方式通过事件总线回到我的处理程序。这些是我目前知道并尝试过的选项,有没有更好的方法来实现这个目标?
- 将列表序列化为 JSON 并存储在
JsonObject
中。这需要在两端显式 serialization/deserialization,这似乎是不必要的:
// Verticle
List<CustomObject> result = method();
JsonObject data = new JsonObject();
data.put("result", Json.encode(result));
msg.reply(data);
// Handler
String serializedList = body.getString("result");
List<CustomObject> list = objectMapper.readValue(serializedList, new TypeReference<List<CustomObject>>(){});
- 为
ArrayList<CustomObject>
定义消息编解码器。从理论上讲,我相信这会起作用,但我在网上看到的所有消息编解码器示例总是关于为 single object 创建编解码器,而我不是完全确定这是否适用于 collections.
是否有更简单的方法适合我的用例但我不知道?谢谢!
抱歉举了一个冗长的例子,但是你可以:
public class EventBusHolder {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.eventBus().registerDefaultCodec(Holder.class, new HolderCodec());
vertx.deployVerticle(new SomeVerticle(), (r) -> {
vertx.eventBus().send("custom", new Holder(new CustomObject("a")));
});
}
}
class HolderCodec implements MessageCodec<Holder, Holder> {
@Override
public void encodeToWire(Buffer buffer, Holder holder) {
}
@Override
public Holder decodeFromWire(int pos, Buffer buffer) {
return null;
}
@Override
public Holder transform(Holder holder) {
return holder;
}
@Override
public String name() {
return "HolderCodec";
}
@Override
public byte systemCodecID() {
return -1;
}
}
class SomeVerticle extends AbstractVerticle {
@Override
public void start() {
vertx.eventBus().consumer("custom", (msg) -> {
System.out.println(msg.body());
});
}
}
class CustomObject {
public String name;
public CustomObject(String name) {
this.name = name;
}
@Override
public String toString() {
return "CustomObject{" +
"name='" + name + '\'' +
'}';
}
}
final class Holder {
@Override
public String toString() {
return "Holder{" +
"data=" + data +
'}';
}
private final List<CustomObject> data;
public Holder(final CustomObject... data) {
this.data = Arrays.asList(data);
}
public List<CustomObject> getData() {
return data;
}
}
请注意,encodeToWire
和 decodeFromWire
未实现。不会为本地消息调用它们。
拥有这个 Holder
对象是绕过 JVM 类型擦除的简单方法。
我有一个在给定端点处理 HTTP 请求的处理程序。处理程序通过事件总线向 Verticle 发送消息,该事件总线进行一些外部分页 REST 调用,聚合结果,然后 returns 将结果返回给处理程序。分页 REST 调用的结果表示为自定义列表 object。如果我只是尝试发送 List
本身,Vertx 会抛出一个异常,抱怨它找不到 java.util.ArrayList
.
我正在尝试找到 "best"——意思是最简单、最有效、最 readable/maintainable——在 Vertx 中发送这些 object 列表的方式通过事件总线回到我的处理程序。这些是我目前知道并尝试过的选项,有没有更好的方法来实现这个目标?
- 将列表序列化为 JSON 并存储在
JsonObject
中。这需要在两端显式 serialization/deserialization,这似乎是不必要的:
// Verticle
List<CustomObject> result = method();
JsonObject data = new JsonObject();
data.put("result", Json.encode(result));
msg.reply(data);
// Handler
String serializedList = body.getString("result");
List<CustomObject> list = objectMapper.readValue(serializedList, new TypeReference<List<CustomObject>>(){});
- 为
ArrayList<CustomObject>
定义消息编解码器。从理论上讲,我相信这会起作用,但我在网上看到的所有消息编解码器示例总是关于为 single object 创建编解码器,而我不是完全确定这是否适用于 collections.
是否有更简单的方法适合我的用例但我不知道?谢谢!
抱歉举了一个冗长的例子,但是你可以:
public class EventBusHolder {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.eventBus().registerDefaultCodec(Holder.class, new HolderCodec());
vertx.deployVerticle(new SomeVerticle(), (r) -> {
vertx.eventBus().send("custom", new Holder(new CustomObject("a")));
});
}
}
class HolderCodec implements MessageCodec<Holder, Holder> {
@Override
public void encodeToWire(Buffer buffer, Holder holder) {
}
@Override
public Holder decodeFromWire(int pos, Buffer buffer) {
return null;
}
@Override
public Holder transform(Holder holder) {
return holder;
}
@Override
public String name() {
return "HolderCodec";
}
@Override
public byte systemCodecID() {
return -1;
}
}
class SomeVerticle extends AbstractVerticle {
@Override
public void start() {
vertx.eventBus().consumer("custom", (msg) -> {
System.out.println(msg.body());
});
}
}
class CustomObject {
public String name;
public CustomObject(String name) {
this.name = name;
}
@Override
public String toString() {
return "CustomObject{" +
"name='" + name + '\'' +
'}';
}
}
final class Holder {
@Override
public String toString() {
return "Holder{" +
"data=" + data +
'}';
}
private final List<CustomObject> data;
public Holder(final CustomObject... data) {
this.data = Arrays.asList(data);
}
public List<CustomObject> getData() {
return data;
}
}
请注意,encodeToWire
和 decodeFromWire
未实现。不会为本地消息调用它们。
拥有这个 Holder
对象是绕过 JVM 类型擦除的简单方法。