Статьи

Все о сообщениях JMS


Поставщики JMS, такие как ActiveMQ, основаны на концепции передачи однонаправленных сообщений между узлами и брокерами асинхронно.
Тщательное знание типов сообщений, которые можно отправлять через промежуточное ПО JMS, может значительно упростить вашу работу по сопоставлению шаблонов связи с реальным кодом.

Базовый интерфейс сообщений

Некоторые члены объекта являются общими для всех сообщений:

  • поля заголовка , используемые для однозначной идентификации сообщения и направления его нужным посредникам и потребителям.
  • Динамическая карта свойств, которые могут программно считываться JMS-брокерами для фильтрации или маршрутизации сообщений.
  • Орган , который дифференцируется в различных реализациях мы увидим.

Поля заголовка

Набор методов getJMS * () в интерфейсе Message определяет доступные заголовки.

Два из них ориентированы на идентификацию сообщений :

  • getJMSMessageID () содержит сгенерированный идентификатор для идентификации сообщения, уникальный, по крайней мере, для текущего брокера. Все сгенерированные идентификаторы начинаются с префикса «ID:», но вы можете переопределить его с помощью соответствующего установщика.
  • getJMSCorrelationID () (и getJMSCorrelationID () как байты) могут связывать сообщение с другим, обычно с тем, которое было отправлено ранее. Например, ответ может нести идентификатор исходного сообщения, если он помещен в другую очередь.

Два для идентификации отправителя и получателя :

  • getJMSDestination () возвращает объект Destination (тема, очередь или их временная версия), описывающая, куда было направлено сообщение.
  • getJMSReplyTo () — объект назначения, куда должны отправляться ответы; это может быть нулевым, конечно.
  • Три настройки механизма доставки:
  • getJMSDeliveryMode () может быть DeliveryMode.NON_PERSISTENT или DeliveryMode.PERSISTENT; Только постоянные сообщения гарантируют доставку в случае сбоя брокеров, которые его транспортируют.
  • getJMSExpiration () возвращает временную метку, указывающую время истечения сообщения; это может быть 0 в сообщении без определенного срока действия.
  • getJMSPriority () возвращает целочисленное значение 0-9 (чем выше, тем лучше), определяющее приоритет для доставки. Это только ценность из лучших усилий.

В то время как остальные содержат метаданные :

  • getJMSRedelivered () возвращает логическое значение, указывающее, доставляется ли сообщение снова после доставки, которая не была подтверждена.
  • getJMSTimestamp () возвращает длинное указание времени отправки.
  • getJMSType () определяет поле для типов сообщений, зависящих от поставщика или приложения.

Из этих заголовков только JMSCorrelationID, JMSReplyTo и JMSType должны быть установлены при необходимости. Другие генерируются или управляются методами send () и publish (), если они не указаны (для каждого из этих заголовков доступны сеттеры).

свойства

Общие свойства со строковым именем можно добавлять к сообщениям и читать с помощью getBooleanProperty (), getStringProperty () и аналогичных методов. Соответствующие сеттеры setBooleanProperty (), setStringProperty (), … могут быть использованы для их добавления.

Причина сохранения некоторых свойств содержимого сообщения (которое может содержать MapMessage) заключается в том, что они могут быть прочитаны до достижения места назначения, например, в JMS-посреднике.

Вариант использования для этого доступа к свойствам сообщений — маршрутизация и фильтрация: нисходящие посредники и потребители могут определить фильтр, такой как «Меня интересуют только сообщения в этой теме, которые имеют свойство X = ‘value’ и Y = ‘value2′».

Тела

Все подинтерфейсы javax.jms.Message, определенные API, предоставляют различные типы тел сообщений (в то время как фактические классы определяются поставщиками и не являются частью API). Фактическая реализация затем обрабатывается сессией, которая реализует шаблон абстрактной фабрики.

На стороне получения приведение необходимо для любого типа сообщения (по крайней мере, в Java JMS Api), так как читается только общее сообщение.

BytesMessage — самый простой тип: он содержит последовательность неинтерпретируемых байтов. Следовательно, теоретически он может содержать что угодно, но генерация и интерпретация контента — это работа клиента.

BytesMessage m = session.createBytesMessage();
m.writeByte(65);
m.writeBytes(new byte[] { 66, 68, 70 });
// on receival (cast shown only here)
BytesMessage m = (BytesMessage) genericMessage;
byte[] content = new byte[4];
m.readBytes(content);

MapMessage определяет сообщение, содержащее (неупорядоченный) набор пар ключ / значение, также называемый картой, словарем или хэшем. Однако ключи являются объектами String, а значения являются примитивами или строками; так как они примитивы, они не должны быть нулевыми.

MapMessage = session.createMapMessage();
m.setString('key', 'value'); // or m.setObject('key', 'value') to avoid specifying a type
// on receival
m.getString('key'); // or m.getObject('key')

ObjectMessage оборачивает универсальный объект для передачи. Объект должен быть Сериализуемым.

ObjectMessage m = session.createObjectMessage();
m.setObject(new ValueObject('field1', 42));
// on receival
ValueObject vo = (ValueObject) m.getObject();

StreamMessage оборачивает поток примитивных значений неопределенной длины.

StreamMessage m = session.createStreamMessage();
m.writeBoolean(true);
m.writeBoolean(false);
m.writeBoolean(true);
// receival
System.out.println(m.readBoolean());
System.out.println(m.readBoolean());
System.out.println(m.readBoolean()); // prints true, false, true

TextMessage оборачивает строку любой длины.

TextMessage m = session.createTextMessage("Contents");
// or use m.setText() afterwards
// receival
String text = m.getText();

Обычно все сообщения находятся в фазе только для чтения после получения, поэтому к ним могут вызываться только получатели.