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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6387947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:41:59  来源:igfitidea点击:

How to send custom XML data using the Smack library?

javaxmlxmppsmack

提问by BinRoot

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

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

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.

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

Any help would be appreciated.

任何帮助,将不胜感激。

采纳答案by shanraisshan

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

您需要定义一个应该实现 ExtensionElement自定义类(如@ 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 replyis a custom extension, which contains

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

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

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

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

回答by Robin

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.

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

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 EmbeddedExtensionProviderfor this as it handles the tag parsing for you, thus simplifying the process.

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

回答by ngoa

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:

您的 XML 消息将如下所示:

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

回答by Femi

You can use a packet extensionfor this: unfortunately there is no good documentation or examples for using packet extensions. I've previously looked at this unresolved questionwhich 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 DocumentHelperand Element.

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

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.

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

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 delayelement) resulted in the packet not being routed. Something in Openfire swallowed it, so this is something to watch for.

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