Как отправить пользовательский 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 проглотил его, так что это то, что нужно посмотреть.