Как лучше всего отправить коллекцию объектов по шине событий в Vertx?
У меня есть обработчик, который обслуживает HTTP-запросы в заданной конечной точке. Обработчик отправляет сообщение о вершине через шину событий, которая выполняет некоторые внешние вызовы REST с разбивкой на страницы, агрегирует результаты и возвращает результаты обратно обработчику. Результат постраничных вызовов REST представлен в виде списка настраиваемых объектов. Если я просто попытаюсь отправитьList
сам Vertx выдает исключение, жалуясь, что не может найти кодек для java.util.ArrayList
.
Я пытаюсь найти "лучший" - то есть самый простой, наиболее эффективный и наиболее читаемый / обслуживаемый - способ в Vertx отправить список этих объектов обратно по шине событий моему обработчику. Это варианты, о которых я знаю и пробовал до сих пор, есть ли лучшие способы добиться этого?
- Сериализовать список в JSON и сохранить в
JsonObject
. Это требует явной сериализации / десериализации на обоих концах, что кажется ненужным:
// 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>
. Теоретически я считаю, что это сработает, но все примеры, которые я видел в Интернете для кодеков сообщений, всегда касаются создания кодека для одного объекта, и я не совсем уверен, сработает ли это для коллекций.
Есть ли более простой метод, который подходит для моего случая использования, о котором я не знаю? Спасибо!
1 ответ
Извините за длинный пример, но вот:
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
object - простой способ обойти стирание типа в JVM.