aSmack - 数据包来使用数据包侦听器的XML输出​​为空的元素 [英] aSmack - Packet to XML using Packet Listener outputs nullable elements

查看:247
本文介绍了aSmack - 数据包来使用数据包侦听器的XML输出​​为空的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用aSmack在我的Andr​​oid应用我的XMPP服务器进行通信,我打开了调试的拍击,所以我可以看到所有的XML的到来/离去。 我在这里的问题是,我使用的是PacketListener,以获取该我给包服务器的响应,但是当我叫包的toxml用于()方法,我得到了一个奇怪的输出。
类和详细信息如下。

I'm using aSmack in my Android app to communicate with my XMPP server, and I turned on the debug for Smack so I could see all the XML's coming/going. My problem here is that I am using a PacketListener to get the server response for the package that I sent, but when I call the toXML() method of the Packet I got an weird output.
Classes and more details below.

我的服务器有XEP-0136实施以来aSmack不具有$ C $下它但我想提出的IQ数据包并发送它,这是按预期工作,因为你可以看到下面我的XML分组,按照设计,在XEP-0136,检索收藏列表(的http:// xmpp.org/extensions/xep-0136.html#manage-list

My server has the XEP-0136 implementation and since aSmack doesn't have the code for it yet I am making the IQ packet and sending it, and this is working as expected, as you can see below my XML Packet, as designed in the XEP-0136, retrieving list of collections( http://xmpp.org/extensions/xep-0136.html#manage-list )

XML封装

06-13 14:11:21.769: D/SMACK(3018): 02:11:21 PM SENT (1079273464): 
<iq id="john@company.com/Smack/Conversations" type="get">
  <list with="john@company.com" xmlns="urn:xmpp:archive">
    <set xmlns="http://jabber.org/protocol/rsm">
      <max>30</max>
    </set>
  </list>
</iq>

要创建这个XML我的XML架构文件作为设计在XEP-0136,并与SimpleXML的LIB我映射的所有元素的帮助下,这是code我用来创建和发送包:

To create this XML I got the XML Schema files as designed in the XEP-0136, and with the help of the SimpleXML lib I mapped all the elements and this is the code I am using to create and send the package:

XMPPService.java

private static final int MAX_LIST = 30;

public void getConversations(String email, BaseActivity activity)
{
    if (isAuthenticated())
    {
        String packetId = connection.getUser() + "/Conversations";
        Set set = new Set();
        set.setMax(MAX_LIST);

        List list = new List();
        list.setWith(email);
        list.setSet(set);

        final IQ iq = new IQ();
        iq.setList(list);
        iq.setType(IQType.get);
        iq.setId(packetId);

        PacketIDFilter filter = new PacketIDFilter(packetId);
        connection.addPacketListener(new ChatListListener(activity), filter);
        sendPacket(iq);
    }
}

public void sendPacket(IQ iq)
{
    if (isAuthenticated())
    {
        connection.sendPacket(new IQPacket(iq));
    }
}

IQPacket.java

public class IQPacket extends Packet {

 private IQ iq;

 public IQPacket(IQ iq)
 {
    this.iq = iq;
 }

 public IQPacket(Packet packet, IQ iq)
 {
    super(packet);
    this.iq = iq;
 }

 @Override
 public String toXML()
 {
    StringWriter writer = new StringWriter();
    Serializer serializer = new Persister();
    try
    {
        serializer.write(iq, writer);
        return writer.getBuffer().toString();
    } catch (Exception e)
    {
        Log.e("COMPANY", "Error serializing xml", e);
    }
    return null;
 }

}

正如我所说的,这部分的作品,我的问题是监听器,当我呼吁收到包裹的toxml用于()方法,我不能让关于聊天中的重要信息,但啪的调试输出打印到我的一切,我希望你可以看到以下信息:

As I said, this part works, my problem is for the Listener, when I call the toXML() method for the package received, I can't get the important information about the chats, but the Smack debugging output prints to me all the information that I'm expecting as you can see below:

啪调试已接收XML

06-13 14:11:21.989: D/SMACK(3018): 02:11:21 PM RCV  (1079273464): 
<iq type="result" id="john@company.com/Smack/Conversations" to="john@company.com/Smack">
  <list xmlns="urn:xmpp:archive">
    <chat with="anotheruser@company.com" start="2013-06-10T13:19:25.000Z"/>
    <chat with="yetanotheruser@company.com" start="2013-06-10T13:36:50.876Z"/>
    <set xmlns="http://jabber.org/protocol/rsm">
      <first index="0">2</first>
      <last>3</last>
      <count>9</count>
    </set>
  </list>
</iq>

另外这个XML是预期的答案,因为我拥有所有这些映射为JavaBean的元素,但是这是我所得到的,当我收到包在我ChatListener并调用toxml用于()方法:

Also this XML is the expected answer since I have all those elements mapped as JavaBeans, but this is what I get when I receive the Packet on my ChatListener and call the toXML() method:

06-13 14:11:22.009: I/System.out(3018): 
<iq id="john@company.com/Smack/Conversations" to="john@company.com/Smack" type="result">nullnullnullnullnullnull2nullnull3nullnull9nullnull</iq>

ChatListListener.java

public class ChatListListener implements PacketListener {

 private BaseActivity activity;

 public ChatListListener(BaseActivity activity)
 {
    this.activity = activity;
 }

 @Override
 public void processPacket(Packet packet)
 {
    activity.notifyPacketReceived();
    System.out.println(packet.toXML());
 }
}

分组是org.jivesoftware.smack.packet.Packet,所以它从aSmack lib中的默认包。

The Packet is from org.jivesoftware.smack.packet.Packet, so it's the default Packet from the aSmack lib.

所以我的问题是,我在做什么不同的拍击调试器?我看着它的code,而我看到的是还要求从包中toxml用于()方法,并添加ReceiveListener。 在这里我的想法是我称之为后toxml用于()我可以使用的SimpleXML将其改造成我IQ.java,我映射,并开始使用它的信息。

So my question is, what am I doing different of the Smack debugger? I looked its code and for what I saw it also calls the toXML() method from the packet and add a ReceiveListener. My idea here is after I call the toXML() I can use SimpleXML to transform it into my IQ.java that I mapped and start using its information.

修改

添加更多的信息。所以,细算起来的拍击code和它如何处理收到的包,我弄清楚,也许我应该使用IQProvider。 所以我注册了我的IQProvider

Adding more information. So after looking up the Smack code and how it handles the package received, I figure out that maybe I should use an IQProvider. So I registered my IQProvider

ProviderManager.getInstance().addIQProvider("list", "urn:xmpp:archive", new ListIQProvider());

在这之后,我把一个断点在我IQProvider的方法 parseIQ(XmlPullParser为arg0),然后包实际上是被发送到我的供应商,但它仍然拥有所有这些null元素。我有点失去了,因为现在我需要这个来继续工作,我会继续调查啪源$ C ​​$ C。

And after that I put a breakpoint on the method parseIQ(XmlPullParser arg0) of my IQProvider, and the package is actually being sent to my provider, but still it has all those null elements. I'm kind lost right now because I need this to keep working, I will keep investigating the Smack source code.

推荐答案

大量的研究和寻找啪源后,我找到了解决办法。 这些步骤是,加IQProvider,添加PacketListener为您的数据包,发送数据包。等待你的IQProvider包,分析它,并得到你的监听你的回应。

After lot of research and looking Smack sources, I found out the solution. The steps are, add IQProvider, add a PacketListener for your packet, send the packet. Wait for the packet on your IQProvider, parse it, and get your response on your Listener.

因此​​, addIQProvider addPacketListener 都没错,问题是,我需要做的XML的完全解析我ListIQProvider,这听起来很简单,但我花了一段时间来弄清这一点。

So the addIQProvider and addPacketListener were both right, the thing is, I need to do the complete parse of the XML on my ListIQProvider, it sounds simple but took me some time to figure that out.

public class ListIQProvider implements IQProvider {

 public ListIQProvider()
 {
 }

 @Override
 public IQ parseIQ(XmlPullParser parser) throws Exception
 {
    Logger.d(String.format("Received iq packet, namespace[%s], name[%s]", parser.getNamespace(), parser.getName()));
    ListIQ iq = new ListIQ();
    ListIQ.Set set = new Set();
    boolean done = false;

    String with = "", start = "";
    while (!done)
    {
        int eventType = parser.next();
        if (eventType == XmlPullParser.START_TAG)
        {
            if (parser.getName().equals("chat"))
            {
                with = parser.getAttributeValue("", "with");
                start = parser.getAttributeValue("", "start");
                iq.addChat(new Chat(with, start));
            }
            else if (parser.getName().equals("first"))
            {
                int index = parseInt(parser.getAttributeValue("", "index"));
                set.setIndexAtt(index);
                int first = parseInt(parser.nextText());
                set.setFirst(first);
            }
            else if (parser.getName().equals("last"))
            {
                int last = parseInt(parser.nextText());
                set.setLast(last);
            }
            else if (parser.getName().equals("count"))
            {
                int count = parseInt(parser.nextText());
                set.setCount(count);
            }
        }
        else if (eventType == XmlPullParser.END_TAG)
        {
            if (parser.getName().equals("list"))
            {
                iq.setSet(set);
                done = true;
            }
        }
    }

    return iq;
 }

 private int parseInt(String integer)
 {
    return Integer.parseInt((integer != null ? integer : "0"));
 }
}

在这之后,我不得不这样做对我的 ChatListListener 被浇铸在以我的 ListIQ 类。而已。 这里的关键是,在分组接收我的 ChatListListener 是一样的分组正被返回的parseIQ方法在我的 ListIQProvider 。 因此,在这个问题/回答,我们有你需要的XEP-0136几乎所有的东西,或者至少开始使用它。 由于我没有在网上找到任何好的和简单的源来帮助我,我分享我的位置。下面这是ListIQ类:

After that, all I had to do on my ChatListListener was casting the Packet to my ListIQ class. That's it. The thing here is, the Packet being received on my ChatListListener is the same Packet that is being returned on the parseIQ method on my ListIQProvider. So in this question/answer we have almost everything you need for XEP-0136, or at least start using it. Since I didn't found any good and simple source on the web to help me, I'm sharing mine here. Below it's the ListIQ class:

public class ListIQ extends IQ {

 private List<Chat> chats;

 private Set set;

 public ListIQ()
 {
    this.chats = new ArrayList<ListIQ.Chat>();
 }

 public Set getSet()
 {
    return set;
 }

 public void setSet(Set set)
 {
    this.set = set;
 }

 public void addChat(Chat chat)
 {
    chats.add(chat);
 }

 public List<Chat> getChats()
 {
    return chats;
 }

 @Override
 public String getChildElementXML()
 {
    StringBuilder builder = new StringBuilder("<list xmlns=\"urn:xmpp:archive\">");
    for (Chat chat : chats)
    {
        builder.append(chat.toXml());
    }
    builder.append(set.toXml());
    builder.append("</list>");
    return builder.toString();
 }

 public static class Chat {
    private String with;
    private String start;

    public Chat()
    {
    }

    public Chat(String with, String start)
    {
        this.with = with;
        this.start = start;
    }

    public String getWith()
    {
        return with;
    }

    public void setWith(String with)
    {
        this.with = with;
    }

    public String getStart()
    {
        return start;
    }

    public void setStart(String start)
    {
        this.start = start;
    }

    public String toXml()
    {
        StringBuilder builder = new StringBuilder("<chat with=\"");
        builder.append(with).append("\"");
        builder.append(" start=\"");
        builder.append(start);
        builder.append("\"/>");
        return builder.toString();
    }

 }

 public static class Set {
    private int last;
    private int count;
    private int indexAtt;
    private int first;

    public Set()
    {
    }

    public int getLast()
    {
        return last;
    }

    public void setLast(int last)
    {
        this.last = last;
    }

    public int getCount()
    {
        return count;
    }

    public void setCount(int count)
    {
        this.count = count;
    }

    public int getIndexAtt()
    {
        return indexAtt;
    }

    public void setIndexAtt(int indexAtt)
    {
        this.indexAtt = indexAtt;
    }

    public int getFirst()
    {
        return first;
    }

    public void setFirst(int first)
    {
        this.first = first;
    }

    public String toXml()
    {
        StringBuilder builder = new StringBuilder("<set xmlns=\"http://jabber.org/protocol/rsm\">");
        builder.append("<first index=\"").append(indexAtt).append("\">").append(first).append("</first>");
        builder.append("<last>").append(last).append("</last>");
        builder.append("<count>").append(count).append("</count>");
        builder.append("</set>");
        return builder.toString();
    }
 }

}

这篇关于aSmack - 数据包来使用数据包侦听器的XML输出​​为空的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆