Как отправить пользовательский XML-пакет с помощью Java Smack API?

Я использую API Smack в Java для подключения к моему серверу XMPP.

Я хочу отправить настроенный пакет сообщений следующим образом:

<message to="[email protected]" type="chat" MYFIELD="custom stuff">
    <body> hi </body>
    <CUSTOM_STANZA A="..." B="..."> 
        C="..." 
        D="..."
    </CUSTOM_STANZA>
</message>

Я предполагаю, что я создаю реализацию своего собственного пакета с возвратом этого XML в него toXML(). Но это не работает.

Любая помощь будет оценена по достоинству.

Ответ 1

Вам нужно определить настраиваемый класс, который должен реализовать ExtensionElement (как показано в <@haqref= "https://stackoverflow.com/users/194894/flow" > Flow )

В этом ответе представлено более подробное объяснение, которое дает следующую строфу

<message id='923442621149' type='chat'><body>shanraisshan</body>
<reply xmlns='shayan:reply' rText='this is custom attribute'/>
</message>

где ответ - это пользовательское расширение, содержащее

  • Элемент (ответ)
  • Пространство имен (shayan: reply)

список стандартных пространств имен xmpp доступен на Официальный веб-сайт XMPP

Ответ 2

Я не знаю, почему вы хотите добавить в сообщение пользовательские атрибуты. Это будет проблематично для клиента и может также вызвать проблемы на сервере, так как оно не будет соответствовать схеме для строфы сообщения.

С другой стороны, содержимое сообщения легко обрабатывается как @Femi с расширением пакета. Вам нужно создать MyExtension, который расширяет пакет PacketExtension, а toXML() в этом классе вернет вашу стандартную строфу.

Вы можете создать и отправить свое собственное сообщение:

Message message = new Message();
message.addExtension(new MyExtension());
chat.sendMessage(message);

Чтобы прочитать строфу, вы захотите зарегистрировать provider, который создаст и вернет ваш собственный пакет PacketExtension. Вы должны посмотреть на EmbeddedExtensionProvider для этого, поскольку он обрабатывает парсинг тегов для вас, тем самым упрощая процесс.

Ответ 3

Недавно я узнал, как добавить пользовательскую строфу в ваше сообщение. Это было довольно легко, как только я понял это. Мне просто нужно было расширить стандартный класс сообщений своим специальным классом сообщений.

public class CustomMessage extends org.jivesoftware.smack.packet.Message {
  public CustomMessage() {
    super();
  }

  private String customStanza;

  /**
   * @param customStanza
   *            the customStanza to set
   */
  public void setCustomStanza(String customStanza) {
    this.customStanza = customStanza;
  }

  @Override
  public String toXML() {
    String XMLMessage = super.toXML();
    String XMLMessage1 = XMLMessage.substring(0, XMLMessage.indexOf(">"));
    String XMLMessage2 = XMLMessage.substring(XMLMessage.indexOf(">"));
    if (this.customStanza != null) {
      XMLMessage1 += " CustomStanza=\"" + this.customStanza + "\"";
    }

    return XMLMessage1 + XMLMessage2;
  }
}

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

CustomMessage message = new CustomMessage();
message.setCustomStanza("my data here");
System.out.println(message.toXML());
muc.sendMessage(message);

Ваше XML-сообщение будет выглядеть следующим образом:

<message id="ee7Y7-8" CustomStanza="my data here"></message>

Ответ 4

Вы можете использовать расширение пакета для этого: к сожалению, нет хорошей документации или примеров использования расширений пакетов. Я ранее смотрел на этот неразрешенный вопрос, в котором есть пример кода, но я не смог заставить его работать: у меня нет никаких исключений, но он просто не сделал" t, поскольку мое расширение не было вызвано, и я перешел к простому кодированию своих данных в теле сообщения.

EDIT: для потомков мне удалось получить следующий код. Он использует классы DOM4J DocumentHelper и Element.

Presence np, packet = new Presence();
        packet.setID(sessionManager.nextStreamID().toString());
        packet.setFrom(server.createJID(operator, null));
        if(!available) packet.setType(Presence.Type.unavailable);
        else packet.setType(null);

        // add the custom XML
        Element xml = DocumentHelper.createElement(QName.get("custom", "http://www.custom.com/xmpp"));
        xml.addAttribute("type", "presenceupdate");
        packet.addExtension(new PacketExtension(xml));

Мягко юмористический: через год я наткнулся на свой собственный ответ, фактически пытаясь решить эту проблему для реального проекта (в отличие от того, чтобы переделывать, как я это делал раньше), и поскольку я не мог просто отказаться от него, мне пришлось это понять вне. Я полагаю, что мне понадобится этот ответ снова, так что вот оно. SO: моя память в небе.

EDIT: нашел еще более простой способ сделать это:

        Element xml = packet.addChildElement("custom", "http://www.custom.com/xmpp");
        xml.addAttribute("type", "presenceupdate");

Замечание: попытка добавить определенные вещи (в моем случае, пытаясь добавить элемент задержки) привела к тому, что пакет не маршрутизировался. Что-то в Openfire проглотил его, так что это то, что нужно посмотреть.