如何使用Java的Smack API发送自定义XML数据包?

我正在使用Java中的Smack API连接到我的XMPP服务器。

我想发送一个这样的自定义消息包:

  hi   C="..." D="..."   

我猜我创建了我自己的Packet,它在它的toXML()方法中返回了这个XML。 但这似乎不起作用。

任何帮助,将不胜感激。

您需要定义一个应该实现ExtensionElement自定义类 (由@Flow分配)

此答案中提供了产生以下节的非常详细的解释

 shanraisshan   

其中reply是自定义扩展,其中包含

  1. 元素 (回复)
  2. 命名空间 (shayan:回复)

官方XMPP网站上提供了默认的xmpp命名空间列表

我不知道你为什么要在邮件中添加自定义属性。 这在客户端上会出现问题,并且可能会导致服务器上出现问题,因为它与消息节的架构不匹配。

另一方面,消息内容很容易处理,因为@Femi说有一个数据包扩展。 您需要创建一个扩展PacketExtension的MyExtension,该类中的toXML()将返回您的自定义节。

您可以通过以下方式创建和发送自定义消息:

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

要阅读该节,您需要注册一个提供程序 ,它将创建并返回您的自定义PacketExtension。 您应该看看EmbeddedExtensionProvider ,因为它为您处理标记解析,从而简化了过程。

我最近发现了如何在邮件中添加自定义节。 一旦我弄清楚它就很容易了。 我只需要使用自定义消息类扩展标准Message Class。

 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消息将如下所示:

  

您可以使用数据包扩展 :遗憾的是,没有好的文档或示例来使用数据包扩展。 我以前看过这个未解决的问题 ,其中包含示例代码,但我无法使其正常工作:我没有例外,但它根本无法正常工作,因为我的扩展没有被调用,我继续编写我的数据消息的正文。

编辑:对于后代,我设法得到以下代码工作。 它使用DOM4J类DocumentHelperElement

 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)); 

温和的幽默:一年后我碰到了自己的答案,实际上是试图为一个真正的项目解决这个问题(而不是像我之前那样修修补补),因为我不能放弃它,我不得不弄明白。 我想我会再次需要这个答案,所以在这里。 所以:我在天空中的记忆。

编辑:找到一种更简单的方法:

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

需要注意的是:尝试添加某些内容(在我的情况下,尝试添加延迟元素)会导致数据包无法路由。 Openfire中的东西吞噬了它,所以这是值得关注的。