如何使用 Smack 库发送自定义 XML 数据?

发布于 2024-11-15 20:28:53 字数 516 浏览 4 评论 0原文

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

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

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

我猜我创建了自己的数据包,并在 toXML() 方法中返回此 XML。但这似乎不起作用。

任何帮助将不胜感激。

I'm using the Smack API in Java to connect to my XMPP server.

I want to send a customized message packet like this:

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

I'm guessing that I create implement my own Packet with that returns this XML in it's toXML() method. But that doesn't seem to work.

Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

春风十里 2024-11-22 20:28:53

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

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

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

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

要阅读该节,您需要注册 provider,它将创建并返回您的自定义 PacketExtension。您应该查看 EmbeddedExtensionProvider 为此,它会为您处理标签解析,从而简化了过程。

i don't know why you want to add custom attributes to the message. This will be problematic on the client and may cause issues on the server as well since it will not match the schema for the message stanza.

The message content, on the other hand is easily handled as @Femi said with a packet extension. You need to create a MyExtension which extends PacketExtension, and the toXML() in that class will return your custom stanza.

You can create and send your custom message by:

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

To read the stanza, you will want to register a provider, which will create and return your custom PacketExtension. You should take a look at the EmbeddedExtensionProvider for this as it handles the tag parsing for you, thus simplifying the process.

落在眉间の轻吻 2024-11-22 20:28:53

我最近发现了如何将自定义节添加到您的消息中。一旦我弄清楚了,这很容易。我只需要使用自定义消息类来扩展标准消息类。

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>

I recently found out how to add custom stanza to your message. Its was quite easy once I figured it out. I just needed to extend the standard Message Class with my custom 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;
  }
}

Then use the custom class to send messages like this:

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

Your XML message would then look like this:

<message id="ee7Y7-8" CustomStanza="my data here"></message>
紫竹語嫣☆ 2024-11-22 20:28:53

您可以使用 数据包扩展:不幸的是,没有使用数据包扩展的良好文档或示例。我之前看过这个未解决的问题,它有示例代码,但我无法让它工作:我没有例外,但它根本不起作用,因为我的扩展没有被调用,我继续将我的数据编码在消息正文中。

编辑:为了后代,我设法使以下代码正常工作。它使用 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));

有点幽默:一年后,当我实际尝试为一个真实的项目解决这个问题时(而不是像以前那样修补),我遇到了自己的答案,因为我不能放弃它,所以我必须弄清楚它。我想我会再次需要这个答案,所以就在这里。 SO:我的记忆在天空。

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

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

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

You can use a packet extension for this: unfortunately there is no good documentation or examples for using packet extensions. I've previously looked at this unresolved question which has example code but I was unable to get it working: I got no exceptions but it simply didn't work as my extension wasn't called and I moved on to just encoding my data in the body of a Message.

EDIT: for posterity, I managed to get the following code working. It uses the DOM4J classes DocumentHelper and 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));

Mildly humorous: I ran into my own answer a year later while actually trying to solve this problem for a real project (as opposed to tinkering like I did before) and since I couldn't just abandon it I had to figure it out. I figure I'll need this answer again so here it is. SO: my memory in the sky.

EDIT: found an even simpler way of doing this:

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

Thing to note: trying to add certain things (in my case, trying to add a delay element) resulted in the packet not being routed. Something in Openfire swallowed it, so this is something to watch for.

岁吢 2024-11-22 20:28:53

您需要定义一个自定义类,它应该实现ExtensionElement(如@提到的) Flow

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

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

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

  1. Element (reply)
  2. Namespace (shayan:reply)

默认 xmpp 命名空间列表可在 XMPP 官方网站

You need to define a custom class that should implements ExtensionElement (as menitioned by @Flow)

A very detailed explanation that produces the following stanza is available in this answer

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

where reply is a custom extension, which contains

  1. Element (reply)
  2. Namespace (shayan:reply)

the list of default xmpp namespaces are available at Official XMPP website

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文