如何检索IQ响应

时间:2016-08-30 21:08:16

标签: java xmpp smack

我正在尝试自动化一些xmpp服务器测试。我将xml节发送到xmpp服务器并验证响应。我可以成功发送节,但我无法检索响应。

我正在使用Smack 4.1.8 api。

这是我发送的节目:

<iq id='123' from='rmorgan@xmppserver.domain.net' to='sandbox@xmppserver.domain.net/resource' type='get'>
<control xmlns='http://domain.com/powertalk/control/2.0'>
<point id='00000000/relay_1A' />
<point id='00000000/relay_2A' />
</control>
</iq>

当我使用PSI客户端发送时,我得到以下回报:

<iq from="sandbox@xmppserver.domain/resource" type="result" to="rmorgan@xmppserver.domain/resource" id="17">
<control xmlns="http://domain.com/powertalk/control/2.0">
<point val="0" id="00000000/relay_1A" ts="2016-08-30T15:52:41.068308Z"/>
<point val="0" id="00000000/relay_2A" ts="2016-08-30T15:52:41.148337Z"/>
</control>
</iq>

这就是我想要检索的内容。

我实际收到的是:

    <iq to='rmorgan@xmppserver.domain.net/resource' from='rmorgan@xmppserver.domain.net' id='c8QbM-8' type='result'>
<query xmlns='jabber:iq:roster'></query>
</iq>

这是我的代码。我想我必须做一些自定义IQ提供程序,但我发现的示例主要是针对Smack 3.x并且无效。

        AbstractXMPPConnection mConnection = this.getConnection();
        try
        {
            final IQ iq = new IQ("control","http://domain.com/powertalk/control/2.0") 
            {
                @Override
                protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) 
                {
                    xml.rightAngleBracket();
                    xml.halfOpenElement("point");
                    xml.attribute("id", "00000000/relay_1A");
                    xml.append(" />");
                    xml.halfOpenElement("point");
                    xml.attribute("id", "00000000/relay_2A");
                    xml.append(" />");

                    return xml;
                }
            };
            iq.setStanzaId("123");
            iq.setFrom("rmorgan@xmppserver.domain.net");
            iq.setType(IQ.Type.get);
            iq.setTo("sandbox@xmppserver.domain.net/resource");
            mConnection.sendStanza(iq);

            // Receive the packet
            IQ iqReceived = (IQ)collector.nextResult(50000);

            // Stop queuing results
            collector.cancel();

            System.out.println("Sent:     " + iq.toXML());
            System.out.println("Received: " + iqReceived.toXML());
            System.out.println("Collector size = " + collector.getCollectedCount()); //returns 0
            System.out.println("collector pollResult = " + collector.pollResult()); //returns null
            System.out.println("collector StanzaFilter = " + collector.getStanzaFilter()); //returns: StanzaIdFilter: id=123
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

我在这里缺少什么?

2 个答案:

答案 0 :(得分:1)

想出来。所以,如果有人有兴趣,这是我的解决方案。 这是我测试我的代码的测试。

  XmppMethods command = new XmppMethods();

  String result;
  result = command.sendXMLCommand("123", "get", "00000000/relay_1A", "00000000/relay_2A");

  System.out.println("result = " + result);

sendXMLCommand方法:

public String sendXMLCommand(String packetID, String type, String... points) throws IOException, XMPPException
    {
        ListIQ result = null;
        try
        {
            this.makeConnection();
            final XMPPConnection mConnection = this.getConnection();
            ServiceProviders.Register_Providers(ProviderManager.getInstance());
            this.login();
            IQConnectionRequest iq = new IQConnectionRequest(packetID, type, points);

            PacketFilter filter = new AndFilter(new PacketIDFilter(iq.getPacketID()),
                    new PacketTypeFilter(IQ.class));
            PacketCollector collector = mConnection.createPacketCollector(filter);

            mConnection.sendPacket(iq);

            result = (ListIQ)collector.nextResult(50000);

            collector.cancel(); 


        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            this.disconnect();
        }
        return result.toXML();

    }

IQConnectionRequest

public class IQConnectionRequest extends IQ 
{        
    protected String[] points;

    public String[] getPoints() 
    {
        return points;
    }

    public void setPoints(String... points)
    {
        this.points = points;
    }


    @Override
    public String getChildElementXML() 
    {
        String body = "<control xmlns=\"http://domain_name.com/powertalk/control/2.0\">";

        for (int i = 0; i<this.points.length; i++)
        {
            body += "<point id='" + this.points[i] + "' />";
        }

        body += "</control>";

        return body;

    }

    /**
     * Create new IQ Connection Request
     *
     * @param username
     * @param password
     */
    public IQConnectionRequest(String packetID, String type, String... points) 
    {
        this.setFrom("user@xmppserver.domain.com");
        this.setTo("user@xmppserver.domain.com/resource");
        this.setPacketID(packetID);
        if (type.toLowerCase().equals("get"))
            this.setType(IQ.Type.GET);
        else if (type.toLowerCase().equals("set"))
            this.setType(IQ.Type.SET);
        else
            System.out.println("ERROR: type of " + type + " is not valid. Valid types = SET, GET");
    }

  }

ListIQProvider:

import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider;
import org.xmlpull.v1.XmlPullParser;

public class ListIQProvider implements IQProvider
{
@Override
 public IQ parseIQ(XmlPullParser parser) throws Exception
 {
    ListIQ iq = new ListIQ();
    boolean done = false;

    String val = "", id = "", ts = "";
    while (!done)
    {
        int eventType = parser.next();
        if (eventType == XmlPullParser.START_TAG)
        {
            if (parser.getName().equals("point"))
            {
                val = parser.getAttributeValue("", "val");
                id = parser.getAttributeValue("", "id");
                ts = parser.getAttributeValue("", "ts");
                iq.addChat(new ListIQ.Chat(val, id, ts));
            }

        }
        else if (eventType == XmlPullParser.END_TAG)
        {
            if (parser.getName().equals("control"))
            {
                done = true;
            }
        }
    }

    return iq;
 }
}

ListIQ:

import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.packet.IQ;
public class ListIQ extends IQ
{

 private List<Chat> chats;

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

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

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

 @Override
 public String getChildElementXML()
 {
    StringBuilder builder = new StringBuilder("<control xmlns=\"http://domain_name.com/powertalk/control/2.0\">");
    for (Chat chat : chats)
    {
        builder.append(chat.toXml());
    }
    builder.append("</control>");
    return builder.toString();
 }

 public static class Chat 
 {
    private String id;
    private String val;
    private String ts;

    public Chat(String val, String id, String ts)
    {
        this.id = id;
        this.val = val;
        this.ts = ts;
    }

    public String getID()
    {
        return id;
    }

    public void setID(String id)
    {
        this.id = id;
    }

    public String getVal()
    {
        return val;
    }

    public void setVal(String val)
    {
        this.val = val;
    }
    public String getTS()
    {
        return ts;
    }

    public void setTS(String ts)
    {
        this.ts = ts;
    }

    public String toXml()
    {
        StringBuilder builder = new StringBuilder("<point val=\"");
        builder.append(val).append("\"");
        builder.append(" id=\"");
        builder.append(id).append("\"");
        builder.append(" ts=\"");
        builder.append(ts);
        builder.append("\"/>");
        return builder.toString();
    }

 }
}

ServiceProviders:

import org.jivesoftware.smack.provider.ProviderManager;

public class ServiceProviders 
{
    public static void Register_Providers(ProviderManager pm)
    {
        pm.addIQProvider("control", "http://domain_name.com/powertalk/control/2.0", new ListIQProvider());

    }
 }

答案 1 :(得分:0)

我放弃了smack 4.1.8,现在尝试使用smack 3.2.1并修改了我的代码。我可以看到我的整个节都按预期发送和接收。

我的代码只返回节的第一行:

<iq id="123" to="user@xmppserver.domain.net/Smack" from="sandbox@xmppserver.domain.net/0004a369d964" type="result"></iq>

我启用了smack调试器,我可以在调试器窗口中看到整个结果节。

我如何得到其余的?

我期待:

<iq from="sandbox@xmppserver.domain/resource" type="result"to="rmorgan@xmppserver.domain/resource" id="123"
<controlxmlns="http://domain.com/powertalk/control/2.0">
<point val="0" id="00000000/relay_1A" ts="2016-08-30T15:52:41.068308Z"/>
<point val="0" id="00000000/relay_2A" ts="2016-08-30T15:52:41.148337Z"/>
</control>
</iq>

这是我的代码:

            final XMPPConnection mConnection = this.getConnection();
            this.login();

            IQConnectionRequest iq = new IQConnectionRequest("00000000/relay_1A", "00000000/relay_1A");

            iq.setTo("sandbox@xmppserver.domain.net/0004a369d964");
            iq.setFrom("user@xmppserver.domain.net");
            iq.setPacketID("123");
            iq.setType(IQ.Type.GET);

            PacketFilter filter = new AndFilter(new PacketIDFilter(iq.getPacketID()),
                    new PacketTypeFilter(IQ.class));
            PacketCollector collector = mConnection.createPacketCollector(filter);
            // Send the iq packet with an invalid namespace
            mConnection.sendPacket(iq);

            IQ result = (IQ)collector.nextResult(50000);
            // Stop queuing results
            collector.cancel();             

            System.out.println("result.getType () = " + result.toXML());

            }