【问题标题】:(a)Smack's IQ.toXml() returns XML without custom child elements(a)Smack 的 IQ.toXml() 返回没有自定义子元素的 XML
【发布时间】:2013-06-28 12:17:37
【问题描述】:

我在一个 android 项目中使用 asmack 最新版本 (asmack-android-8-source-0.8.3) 并且 我有以下代码:

connection.addPacketListener(new PacketListener()
{
    @Override
    public void processPacket(Packet p)
    {
        if(p.getPacketID().equals("v3"))
        {
            Log.e("TAG", p.toXML());
        }
    }
}, new IQTypeFilter(IQ.Type.RESULT));


Packet iq = new Packet() 
{
    @Override
    public String toXML() 
    {
        String str = "<iq type='get' id='v3'><getservertime xmlns='urn:xmpp:mrpresence'/></iq>";
        Log.e("TAG", str);
        return str;
    }
};

//sends <iq type='get' id='v3'><getservertime xmlns='urn:xmpp:mrpresence'/></iq>
connection.sendPacket(iq);

在调试器中响应正常,这是预期的:

<iq type="result" id="v3" to="minimaal@mrserver/Smack">
    <servertime xmlns="urn:xmpp:mrpresence" utc="2013-06-28T11:45:32.380Z" local="2013-06-28T07:45:32.380Z"/>
</iq>

但是包列表器中的 p.toXML() 缺少标签“servertime”:

<iq id="v3" to="minimaal@mrserver/Smack" type="result"></iq>

关于我做错了什么有什么建议吗?

【问题讨论】:

    标签: android xmpp package smack asmack


    【解决方案1】:

    &lt;servertime/&gt; 是一个自定义子元素,Smack 不知道它。解析节时它被简单地忽略。您需要通过创建一个新的 PacketExtension 来让 Smack 了解该元素,该 ProviderManager 需要注册。

    您可以在 Smack 关于Provider Architecture 的文档中阅读更多相关信息。

    【讨论】:

    • 我用 ProviderManager.getInstance().addExtensionProvider(packetExtensionProvider) 添加了一个 PacketExtensionProvider,与本教程中的一样:oneminutedistraction.wordpress.com/2010/08/31/…,但我的 PacketExtensionProvider 永远不会被调用。我还使用 connection.addPacketListener() 吗?谢谢。
    • 我也查看了这个源代码:github.com/rummble/jfexmpp 和这个 github.com/redsolution/xabber-android 但没有成功:(
    • @Flow 你能详细说明如何创建一个新的 PacketExtension 并将其注册到 ProviderManager。
    【解决方案2】:

    我通过扩展 IQ 和 IQProvider 类解决了这个问题:

    ServerTime_IQProvider.java

    public class ServerTime_IQProvider implements IQProvider
    {
        public static final String NAMESPACE = "urn:xmpp:mrpresence";
        public static final String ELEMENT_NAME = "servertime";
        public static final String UTC = "utc";
        public static final String LOCAL = "local";
        private Map<String, String> list = new HashMap<String, String>();
    
        @Override
        public IQ parseIQ(XmlPullParser parser) throws Exception
        {
            boolean stop = false;
            String name = parser.getName();
    
            while(false == stop)
            {
                switch (parser.getEventType())
                {
                    case XmlPullParser.START_TAG:
                    {
                        if(ELEMENT_NAME.equals(name))
                        {
                            list.put(UTC, parser.getAttributeValue("", UTC));
                            list.put(LOCAL, parser.getAttributeValue("", LOCAL));
                        }
    
                        break;
                    }
                    case XmlPullParser.END_TAG:
                    {
                        stop = ELEMENT_NAME.equals(name);
                        break;
                    }
                }
            }
    
            name = null;
            return new ServerTime_IQ(list);
        }
    }
    

    ServerTime_IQ.java

    public class ServerTime_IQ extends IQ
    {
        public static final String ID = "servertime";
        private Map<String, String> list;
    
        public ServerTime_IQ(Map<String, String> l)
        {
            list = l;
        }
    
        @Override
        public String getChildElementXML()
        {
            return null;
        }
    
        public String getServerTime_UTC()
        {
            return list.get(ServerTime_IQProvider.UTC);
        }
    
        public String getServerTime_Local()
        {
            return list.get(ServerTime_IQProvider.LOCAL);
        }
    }
    

    然后我将 ServerTime 提供程序添加到 IQProvider 的列表中:

    ProviderManager.getInstance().addIQProvider(ServerTime_IQProvider.ELEMENT_NAME, ServerTime_IQProvider.NAMESPACE, new ServerTime_IQProvider());
    

    这将确保来自服务器的 xml 响应将被我的自定义解析器 (ServerTime_IQProvider) 解析,它知道自定义标签,而不是使用 asmack 的默认解析器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      • 1970-01-01
      • 2015-05-14
      相关资源
      最近更新 更多