Возможно ли иметь приемник асинхронных сообщений в Spring AMQP, который обрабатывает несколько типов контента?

Я использую асинхронный приемник сообщений в Spring-AMQP для получения сообщений. В настоящее время обрабатываются только сообщения с содержимым JSON, но у меня есть требование также обрабатывать сообщения с содержимым XML. Моя текущая реализация MessageListener имеет внедренный MessageConverter и использует его в onMessage(Message), например:

MyMessage myMessage = (MyMessage) jsonConverter.fromMessage(message);

Чтобы поддерживать разные типы контента, я, очевидно, мог бы использовать MessageProperties для опроса заголовка типа контента и вручную выбрать конвертер для использования. Но это кажется большой работой, так как Spring должен обеспечить лучшую поддержку для этого сценария. Я надеялся найти общую реализацию MessageConverter, которая бы сопоставляла типы содержимого с конкретными преобразователями, но, похоже, такой вещи не существует.

Является ли мой лучший вариант написать такой преобразователь делегирования? Или есть способ настроить ListenerContainer для поддержки как асинхронного приема , так и нескольких преобразователей, которые автоматически используются по мере необходимости?


person E-Riz    schedule 06.03.2014    source источник


Ответы (1)


У нас есть открытая проблема JIRA с запросом поддержки для CompositeMessageConverter.

Контейнер прослушивателя не поддерживает преобразование, но у нас есть MessageListenerAdapter, который их поддерживает (но только один, и имеет другие вещи, такие как обработка ответов).

Использование адаптера означает, что вы можете использовать метод POJO на своем слушателе...

public void handleMessage(MyObject foo) {...}

Если вы поместите делегирующий преобразователь (тот, который делегирует либо json, либо упорядочивающий преобразователь) в MLA, и оба преобразователя создадут один и тот же тип объекта, это будет работать нормально. В противном случае подпись должна пройти Object, и вам придется выполнить instanceof тестов.

В какой-то момент я хотел бы сделать адаптер немного умнее, чтобы он мог выбирать метод на основе типа объекта, созданного преобразователем...

public void handleMessage(Foo foo) {...}

public void handleMessage(Bar bar) {...}

...но это совсем другой вопрос.

Если вы придумали полезный конвертер, который хотели бы внести в фреймворк, воспользуйтесь следующими рекомендациями: на вики проекта.

person Gary Russell    schedule 06.03.2014
comment
Спасибо, @gary-russel. Просто чтобы убедиться, что я ясно понимаю, вы говорите, что единственный вариант прямо сейчас - написать делегирующий/составной преобразователь, который выбирает на основе типа содержимого сообщения. Верный? - person E-Riz; 07.03.2014
comment
У меня работает базовый преобразователь делегирования; это почти тривиально, поэтому просмотр и следование рекомендациям проекта займет больше времени, чем его написание ;-) О, и мне также нужно написать несколько модульных тестов. Так что я бы хотел внести свой вклад, но, вероятно, сейчас это маловероятно. - person E-Riz; 07.03.2014
comment
Как обрабатывать тип сообщения с помощью адаптера? Это работало, когда я использовал String, но как только я изменил его на Message, я получаю исключение, вызванное: java.lang.NoSuchMethodException: com.my.myObject.myMethod([B) at java.lang.Class. getMethod(Class.java:1665) в org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:178) в org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter.invokeListenerMethod(MessageListenerAdapter.java:466) .. , еще 12 - person vishal; 19.05.2014
comment
Адаптер предназначен, эээ, для адаптации сообщений. Если вы хотите получить само сообщение, реализуйте MessageListener.onMessage(). - person Gary Russell; 19.05.2014
comment
Я добавил некоторый код в задачу JIRA; см. jira.spring.io/browse/ - person E-Riz; 07.01.2015