我正在尝试自动化一些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();
}
}
我在这里缺少什么?
答案 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());
}