Java 在Vertx中,通过事件总线发送对象集合的最佳方式是什么?

Java 在Vertx中,通过事件总线发送对象集合的最佳方式是什么?,java,vert.x,vertx-eventbus,Java,Vert.x,Vertx Eventbus,我有一个处理程序,在给定的端点上为HTTP请求提供服务。处理程序通过事件总线发送一条垂直消息,该消息发出一些外部分页REST调用,聚合结果,并将结果返回给处理程序。分页REST调用的结果表示为自定义对象列表。如果我只是尝试发送列表本身,Vertx会抛出一个异常,抱怨它找不到java.util.ArrayList的编解码器 我试图在Vertx中找到一种最好的方法,即最简单、最有效、最可读/可维护的方法,通过事件总线将这些对象的列表发送回我的处理程序。这些都是我知道的,并且到目前为止已经尝试过的选择

我有一个处理程序,在给定的端点上为HTTP请求提供服务。处理程序通过事件总线发送一条垂直消息,该消息发出一些外部分页REST调用,聚合结果,并将结果返回给处理程序。分页REST调用的结果表示为自定义对象列表。如果我只是尝试发送列表本身,Vertx会抛出一个异常,抱怨它找不到java.util.ArrayList的编解码器

我试图在Vertx中找到一种最好的方法,即最简单、最有效、最可读/可维护的方法,通过事件总线将这些对象的列表发送回我的处理程序。这些都是我知道的,并且到目前为止已经尝试过的选择,有没有更好的方法来实现这一点

将列表序列化为JSON并存储在JsonObject中。这需要在两端进行显式序列化/反序列化,这似乎是不必要的: 为ArrayList定义消息编解码器。理论上,我相信这是可行的,但我在网上看到的所有消息编解码器示例都是关于为单个对象创建编解码器的,我不完全确定这是否适用于集合。
有没有一种更简单的方法适合我的用例,而我却不知道?谢谢

很抱歉给你举了一个很长的例子,但你可以这样做:

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;
    }
}
请注意,EncodeTowWire和decodeFromWire未实现。本地消息不会调用它们


拥有这个Holder对象是在JVM上绕过类型擦除的一种简单方法。

是否使用集群事件总线?如果没有,您只需创建holder对象,就不会发生序列化。我不使用集群事件总线。你能澄清一下你所说的持有者对象是什么意思吗?你能发布一段代码片段来说明你的意思吗?我明白了,这更有意义。在接收事件总线消息的垂直体中,我可以直接从消息体中拉出Holder对象,比如Holder Holder=Holder msg.body?然后用list list=holder.getData获取内部的基础列表?是的,因为您处于同一个JVM进程中。谢谢,这应该正是我需要做的。仅供参考,我通常看到您创建的“Holder”类被称为“wrapper”,这就是为什么您第一次评论时我有点困惑的原因。谢谢包装器用于功能,支架用于数据。我很乐意帮忙:
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;
    }
}