2012-09-18 26 views
1

我想要接收的消息包。使用asmack for android在XMPP數據包的消息標記中添加自定義屬性?

<message to="[email protected]/smack" chat_id="73392" 
      custom_packet="true" user_id="44" manager_id="39" time_stamp="0" website_id="0" 
      visitor_name="John" end_time="False" xml:lang="en-us" type="groupchat" 
      from="[email protected]/39"> 
      <body>Hello</body> 
      <x xmlns="http://jabber.org/protocol/muc#user"> 
      <status xmlns="" code="0"/> 
      </x></message> 

我收到的消息包。

<message to="[email protected]/Smack" 
    from="[email protected]/Visitor1171" type="groupchat"> 
    <body>Hello</body> 
    <delay xmlns="urn:xmpp:delay"></delay> 
    <x xmlns="jabber:x:delay" stamp="20120917T05:57:19" 
    from="[email protected]/4732abb5"> 
    </x></message> 

我有一個smack的源代碼,這裏是包類。任何人都可以幫我做我的自定義數據包。任何幫助修改源代碼表示讚賞。

代碼:

public abstract class Packet { 

protected static final String DEFAULT_LANGUAGE = 
     java.util.Locale.getDefault().getLanguage().toLowerCase(); 

private static String DEFAULT_XML_NS = null; 

/** 
* Constant used as packetID to indicate that a packet has no id. To indicate that a packet 
* has no id set this constant as the packet's id. When the packet is asked for its id the 
* answer will be <tt>null</tt>. 
*/ 
public static final String ID_NOT_AVAILABLE = "ID_NOT_AVAILABLE"; 

/** 
* Date format as defined in XEP-0082 - XMPP Date and Time Profiles. 
* The time zone is set to UTC. 
* <p> 
* Date formats are not synchronized. Since multiple threads access the format concurrently, 
* it must be synchronized externally. 
*/ 
public static final DateFormat XEP_0082_UTC_FORMAT = new SimpleDateFormat(
       "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); 
static { 
    XEP_0082_UTC_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC")); 
} 


/** 
* A prefix helps to make sure that ID's are unique across mutliple instances. 
*/ 
private static String prefix = StringUtils.randomString(5) + "-"; 

/** 
* Keeps track of the current increment, which is appended to the prefix to 
* forum a unique ID. 
*/ 
private static long id = 0; 

private String xmlns = DEFAULT_XML_NS; 

/** 
* Returns the next unique id. Each id made up of a short alphanumeric 
* prefix along with a unique numeric value. 
* 
* @return the next id. 
*/ 
public static synchronized String nextID() { 
    return prefix + Long.toString(id++); 
} 

public static void setDefaultXmlns(String defaultXmlns) { 
    DEFAULT_XML_NS = defaultXmlns; 
} 

private String packetID = null; 
private String to = null; 
private String from = null; 
private final List<PacketExtension> packetExtensions 
     = new CopyOnWriteArrayList<PacketExtension>(); 

private final Map<String,Object> properties = new HashMap<String, Object>(); 
private XMPPError error = null; 

/** 
* Returns the unique ID of the packet. The returned value could be <tt>null</tt> when 
* ID_NOT_AVAILABLE was set as the packet's id. 
* 
* @return the packet's unique ID or <tt>null</tt> if the packet's id is not available. 
*/ 
public String getPacketID() { 
    if (ID_NOT_AVAILABLE.equals(packetID)) { 
     return null; 
    } 

    if (packetID == null) { 
     packetID = nextID(); 
    } 
    return packetID; 
} 

/** 
* Sets the unique ID of the packet. To indicate that a packet has no id 
* pass the constant ID_NOT_AVAILABLE as the packet's id value. 
* 
* @param packetID the unique ID for the packet. 
*/ 
public void setPacketID(String packetID) { 
    this.packetID = packetID; 
} 

/** 
* Returns who the packet is being sent "to", or <tt>null</tt> if 
* the value is not set. The XMPP protocol often makes the "to" 
* attribute optional, so it does not always need to be set.<p> 
* 
* The StringUtils class provides several useful methods for dealing with 
* XMPP addresses such as parsing the 
* {@link StringUtils#parseBareAddress(String) bare address}, 
* {@link StringUtils#parseName(String) user name}, 
* {@link StringUtils#parseServer(String) server}, and 
* {@link StringUtils#parseResource(String) resource}. 
* 
* @return who the packet is being sent to, or <tt>null</tt> if the 
*  value has not been set. 
*/ 
public String getTo() { 
    return to; 
} 

/** 
* Sets who the packet is being sent "to". The XMPP protocol often makes 
* the "to" attribute optional, so it does not always need to be set. 
* 
* @param to who the packet is being sent to. 
*/ 
public void setTo(String to) { 
    this.to = to; 
} 

/** 
* Returns who the packet is being sent "from" or <tt>null</tt> if 
* the value is not set. The XMPP protocol often makes the "from" 
* attribute optional, so it does not always need to be set.<p> 
* 
* The StringUtils class provides several useful methods for dealing with 
* XMPP addresses such as parsing the 
* {@link StringUtils#parseBareAddress(String) bare address}, 
* {@link StringUtils#parseName(String) user name}, 
* {@link StringUtils#parseServer(String) server}, and 
* {@link StringUtils#parseResource(String) resource}. 
* 
* @return who the packet is being sent from, or <tt>null</tt> if the 
*  value has not been set. 
*/ 
public String getFrom() { 
    return from; 
} 

/** 
* Sets who the packet is being sent "from". The XMPP protocol often 
* makes the "from" attribute optional, so it does not always need to 
* be set. 
* 
* @param from who the packet is being sent to. 
*/ 
public void setFrom(String from) { 
    this.from = from; 
} 

/** 
* Returns the error associated with this packet, or <tt>null</tt> if there are 
* no errors. 
* 
* @return the error sub-packet or <tt>null</tt> if there isn't an error. 
*/ 
public XMPPError getError() { 
    return error; 
} 

/** 
* Sets the error for this packet. 
* 
* @param error the error to associate with this packet. 
*/ 
public void setError(XMPPError error) { 
    this.error = error; 
} 

/** 
* Returns an unmodifiable collection of the packet extensions attached to the packet. 
* 
* @return the packet extensions. 
*/ 
public synchronized Collection<PacketExtension> getExtensions() { 
    if (packetExtensions == null) { 
     return Collections.emptyList(); 
    } 
    return Collections.unmodifiableList(new ArrayList<PacketExtension>(packetExtensions)); 
} 

/** 
* Returns the first extension of this packet that has the given namespace. 
* 
* @param namespace the namespace of the extension that is desired. 
* @return the packet extension with the given namespace. 
*/ 
public PacketExtension getExtension(String namespace) { 
    return getExtension(null, namespace); 
} 

/** 
* Returns the first packet extension that matches the specified element name and 
* namespace, or <tt>null</tt> if it doesn't exist. If the provided elementName is null 
* than only the provided namespace is attempted to be matched. Packet extensions are 
* are arbitrary XML sub-documents in standard XMPP packets. By default, a 
* DefaultPacketExtension instance will be returned for each extension. However, 
* PacketExtensionProvider instances can be registered with the 
* {@link org.jivesoftware.smack.provider.ProviderManager ProviderManager} 
* class to handle custom parsing. In that case, the type of the Object 
* will be determined by the provider. 
* 
* @param elementName the XML element name of the packet extension. (May be null) 
* @param namespace the XML element namespace of the packet extension. 
* @return the extension, or <tt>null</tt> if it doesn't exist. 
*/ 
public PacketExtension getExtension(String elementName, String namespace) { 
    if (namespace == null) { 
     return null; 
    } 
    for (PacketExtension ext : packetExtensions) { 
     if ((elementName == null || elementName.equals(ext.getElementName())) 
       && namespace.equals(ext.getNamespace())) 
     { 
      return ext; 
     } 
    } 
    return null; 
} 

/** 
* Adds a packet extension to the packet. 
* 
* @param extension a packet extension. 
*/ 
public void addExtension(PacketExtension extension) { 
    packetExtensions.add(extension); 
} 

/** 
* Removes a packet extension from the packet. 
* 
* @param extension the packet extension to remove. 
*/ 
public void removeExtension(PacketExtension extension) { 
    packetExtensions.remove(extension); 
} 

/** 
* Returns the packet property with the specified name or <tt>null</tt> if the 
* property doesn't exist. Property values that were orginally primitives will 
* be returned as their object equivalent. For example, an int property will be 
* returned as an Integer, a double as a Double, etc. 
* 
* @param name the name of the property. 
* @return the property, or <tt>null</tt> if the property doesn't exist. 
*/ 
public synchronized Object getProperty(String name) { 
    if (properties == null) { 
     return null; 
    } 
    return properties.get(name); 
} 

/** 
* Sets a property with an Object as the value. The value must be Serializable 
* or an IllegalArgumentException will be thrown. 
* 
* @param name the name of the property. 
* @param value the value of the property. 
*/ 
public synchronized void setProperty(String name, Object value) { 
    if (!(value instanceof Serializable)) { 
     throw new IllegalArgumentException("Value must be serialiazble"); 
    } 
    properties.put(name, value); 
} 

/** 
* Deletes a property. 
* 
* @param name the name of the property to delete. 
*/ 
public synchronized void deleteProperty(String name) { 
    if (properties == null) { 
     return; 
    } 
    properties.remove(name); 
} 

/** 
* Returns an unmodifiable collection of all the property names that are set. 
* 
* @return all property names. 
*/ 
public synchronized Collection<String> getPropertyNames() { 
    if (properties == null) { 
     return Collections.emptySet(); 
    } 
    return Collections.unmodifiableSet(new HashSet<String>(properties.keySet())); 
} 

/** 
* Returns the packet as XML. Every concrete extension of Packet must implement 
* this method. In addition to writing out packet-specific data, every sub-class 
* should also write out the error and the extensions data if they are defined. 
* 
* @return the XML format of the packet as a String. 
*/ 
public abstract String toXML(); 

/** 
* Returns the extension sub-packets (including properties data) as an XML 
* String, or the Empty String if there are no packet extensions. 
* 
* @return the extension sub-packets as XML or the Empty String if there 
* are no packet extensions. 
*/ 
protected synchronized String getExtensionsXML() { 
    StringBuilder buf = new StringBuilder(); 
    // Add in all standard extension sub-packets. 
    for (PacketExtension extension : getExtensions()) { 
     buf.append(extension.toXML()); 
    } 
    // Add in packet properties. 
    if (properties != null && !properties.isEmpty()) { 
     buf.append("<properties xmlns=\"http://www.jivesoftware.com/xmlns/xmpp/properties\">"); 
     // Loop through all properties and write them out. 
     for (String name : getPropertyNames()) { 
      Object value = getProperty(name); 
      buf.append("<property>"); 
      buf.append("<name>").append(StringUtils.escapeForXML(name)).append("</name>"); 
      buf.append("<value type=\""); 
      if (value instanceof Integer) { 
       buf.append("integer\">").append(value).append("</value>"); 
      } 
      else if (value instanceof Long) { 
       buf.append("long\">").append(value).append("</value>"); 
      } 
      else if (value instanceof Float) { 
       buf.append("float\">").append(value).append("</value>"); 
      } 
      else if (value instanceof Double) { 
       buf.append("double\">").append(value).append("</value>"); 
      } 
      else if (value instanceof Boolean) { 
       buf.append("boolean\">").append(value).append("</value>"); 
      } 
      else if (value instanceof String) { 
       buf.append("string\">"); 
       buf.append(StringUtils.escapeForXML((String)value)); 
       buf.append("</value>"); 
      } 
      // Otherwise, it's a generic Serializable object. Serialized objects are in 
      // a binary format, which won't work well inside of XML. Therefore, we base-64 
      // encode the binary data before adding it. 
      else { 
       ByteArrayOutputStream byteStream = null; 
       ObjectOutputStream out = null; 
       try { 
        byteStream = new ByteArrayOutputStream(); 
        out = new ObjectOutputStream(byteStream); 
        out.writeObject(value); 
        buf.append("java-object\">"); 
        String encodedVal = StringUtils.encodeBase64(byteStream.toByteArray()); 
        buf.append(encodedVal).append("</value>"); 
       } 
       catch (Exception e) { 
        e.printStackTrace(); 
       } 
       finally { 
        if (out != null) { 
         try { 
          out.close(); 
         } 
         catch (Exception e) { 
          // Ignore. 
         } 
        } 
        if (byteStream != null) { 
         try { 
          byteStream.close(); 
         } 
         catch (Exception e) { 
          // Ignore. 
         } 
        } 
       } 
      } 
      buf.append("</property>"); 
     } 
     buf.append("</properties>"); 
    } 
    return buf.toString(); 
} 

public String getXmlns() { 
    return this.xmlns; 
} 

public static String getDefaultLanguage() { 
    return DEFAULT_LANGUAGE; 
} 


@Override 
public boolean equals(Object o) { 
    if (this == o) return true; 
    if (o == null || getClass() != o.getClass()) return false; 

    Packet packet = (Packet) o; 

    if (error != null ? !error.equals(packet.error) : packet.error != null) { return false; } 
    if (from != null ? !from.equals(packet.from) : packet.from != null) { return false; } 
    if (!packetExtensions.equals(packet.packetExtensions)) { return false; } 
    if (packetID != null ? !packetID.equals(packet.packetID) : packet.packetID != null) { 
     return false; 
    } 
    if (properties != null ? !properties.equals(packet.properties) 
      : packet.properties != null) { 
     return false; 
    } 
    if (to != null ? !to.equals(packet.to) : packet.to != null) { return false; } 
    return !(xmlns != null ? !xmlns.equals(packet.xmlns) : packet.xmlns != null); 
} 

@Override 
public int hashCode() { 
    int result; 
    result = (xmlns != null ? xmlns.hashCode() : 0); 
    result = 31 * result + (packetID != null ? packetID.hashCode() : 0); 
    result = 31 * result + (to != null ? to.hashCode() : 0); 
    result = 31 * result + (from != null ? from.hashCode() : 0); 
    result = 31 * result + packetExtensions.hashCode(); 
    result = 31 * result + properties.hashCode(); 
    result = 31 * result + (error != null ? error.hashCode() : 0); 
    return result; 
} 
} 
+5

作爲額外的屬性** **從來沒有把自定義的數據('visitor_name','end_time')已定義的XMPP元素('消息')。總是創建一個額外的數據包擴展來添加您的自定義數據,否則您必須很快地處理所涉及的XMPP庫的來源。 – Flow

+2

參見[XEP-134 2.1](http://xmpp.org/extensions/xep-0134.html#xmpp)。 – Flow

+0

@Flow是你正確的,但在那個時候,沒有人給我這樣的想法。如果您向我提供一些創建數據包擴展並添加自定義數據的代碼,我仍然非常感謝 –

回答

3

我在Packet Class中添加了新的字段,並在那裏寫了Getter和Setter。

private String chat_id = null; 
private String custom_packet = null; 
private String user_id=null; 
private String manager_id=null; 
private String time_stamp=null; 
private String website_id=null; 
private String visitor_name=null; 
private String end_time=null; 




public String getChat_id() { 
    return chat_id; 
} 

public void setChat_id(String chat_id) { 
    this.chat_id = chat_id; 
} 

public String getCustom_packet() { 
    return custom_packet; 
} 

public void setCustom_packet(String custom_packet) { 
    this.custom_packet = custom_packet; 
} 

public String getUser_id() { 
    return user_id; 
} 

public void setUser_id(String user_id) { 
    this.user_id = user_id; 
} 

public String getManager_id() { 
    return manager_id; 
} 

public void setManager_id(String manager_id) { 
    this.manager_id = manager_id; 
} 

public String getTime_stamp() { 
    return time_stamp; 
} 

public void setTime_stamp(String time_stamp) { 
    this.time_stamp = time_stamp; 
} 

public String getWebsite_id() { 
    return website_id; 
} 

public void setWebsite_id(String website_id) { 
    this.website_id = website_id; 
} 

public String getVisitor_name() { 
    return visitor_name; 
} 

public void setVisitor_name(String visitor_name) { 
    this.visitor_name = visitor_name; 
} 

public String getEnd_time() { 
    return end_time; 
} 

public void setEnd_time(String end_time) { 
    this.end_time = end_time; 
} 

然後我將此添加到PacketParserUtils類parseMessage()方法。

// ------------------------------CUSTOM ATTRIBUTES----------------------------- 
    message.setChat_id(parser.getAttributeValue("", "chat_id")); 
    message.setCustom_packet(parser.getAttributeValue("", "custom_packet")); 
    message.setUser_id(parser.getAttributeValue("", "user_id")); 
    message.setManager_id(parser.getAttributeValue("", "manager_id")); 
    message.setTime_stamp(parser.getAttributeValue("", "time_stamp")); 
    message.setWebsite_id(parser.getAttributeValue("", "website_id")); 
    message.setVisitor_name(parser.getAttributeValue("", "visitor_name")); 
    message.setEnd_time(parser.getAttributeValue("", "end_time")); 

    // ----------------------------------------------------------------------------- 

然後我更新了Message Class toXML()方法。

// ------------------------------CUSTOM TAGS----------------------------- 

    if(getChat_id()!=null) 
    { 
     buf.append(" chat_id=\"").append(StringUtils.escapeForXML(getChat_id())).append("\""); 

    } 
    if(getCustom_packet()!=null) 
    { 
     buf.append(" custom_packet=\"").append(StringUtils.escapeForXML(getCustom_packet())).append("\""); 

    } 
    if(getUser_id()!=null) 
    { 
     buf.append(" user_id=\"").append(StringUtils.escapeForXML(getUser_id())).append("\""); 

    } 

    if(getManager_id()!=null) 
    { 
     buf.append(" manager_id=\"").append(StringUtils.escapeForXML(getManager_id())).append("\""); 

    } 
    if(getTime_stamp()!=null) 
    { 
     buf.append(" time_stamp=\"").append(StringUtils.escapeForXML(getTime_stamp())).append("\""); 

    } 
    if(getWebsite_id()!=null) 
    { 
     buf.append(" website_id=\"").append(StringUtils.escapeForXML(getWebsite_id())).append("\""); 

    } 
    if(getVisitor_name()!=null) 
    { 
     buf.append(" visitor_name=\"").append(StringUtils.escapeForXML(getVisitor_name())).append("\""); 

    } 
    if(getEnd_time()!=null) 
    { 
     buf.append(" end_time=\"").append(StringUtils.escapeForXML(getEnd_time())).append("\""); 

    } 

    //------------------------------------------------------------------------------------ 

這是我如何能夠在MESSAGE TAG中接收自定義屬性。

+0

tnx這個答案,但即時通訊自定義屬性的空值。你可以幫我嗎? –

+0

@ChiragShah您是否正確更改源代碼? –

+0

是的,我得到了解決方案,這是一點點我的錯誤。 –

8

即使我認爲這是錯誤的做法,因爲我在你的另一個問題說。這些只是你想要做的一些指導。

您不需要修改數據包,只需將消息放入您自己的自定義屬性即可。這將完成發送所需的內容。對於接收,您將不得不修改PacketParserUtil.parseMessage()以確定是否正在發送您的自定義消息或標準消息,並根據需要進行構建和填充。我不知道你使用的服務器是否有問題,因爲它不是標準的,但它可能會工作。

另一個更簡單的選擇是簡單地通過Packet.setProperty()將屬性作爲屬性添加到標準消息中,當然也可以通過getProperty()讀取。這將創建和擴展數據包,但不需要定製工作,因爲Smack已經可以讀取/寫入擴展。

+0

Thankyou。這正是我所做的,它解決了這個問題。我修改了Packet Class並修改了PacketParserUtils類的parseMessage()方法。 –

+0

我可以在不更改源代碼的情況下接收上述數據包嗎? –

+0

如果我確實擴展PacketParserUtils或Message類,是否有任何方法來註冊這些類,還是必須包含所有的源代碼而不是jar? – sbaar

0

如果您可以添加使用像smack中描述的自定義數據包擴展名,那麼請執行此操作。如果您正在尋找與不支持這樣的擴展,就像如果服務器不會存儲它的服務器或不咂嘴客戶端兼容,那麼使用

message.addBody("varName","varValue); 

<message id='8dbda9a2-1f98-478f-9a65-635f181a6ddc' 
to='[email protected]/oGghwFpcrR' type='chat'><body>abcd</body> 
<body xml:lang='varName'>varValue</body><thread>8b5342dcc</thread>   
</message> 

message.getBody("varName"); 

不是一個理想的解決方案,但誰使用無論如何,一個相同的消息多個朗?什麼Smack 應該允許你做的是註冊你自己的消息解析來取代默認的,或至少除了默認的

0

我們有同樣的問題。這裏是一個通用標籤價值的解決方案:

在分組分類,加入:

public static ArrayList<String> parseTags = new ArrayList<String>(); 
public HashMap<String, String> mTags ; 

構造: mTags =新的HashMap(); 複製構造函數: mTags = p。mTags;

在PacketParserUtils.ParseMessage()中,加入

if (message.mTags != null) { 
     for (int i=0; i<Packet.parseTags.size(); i++) { 
      String tag = Packet.parseTags.get(i); 
      String value = parser.getAttributeValue("", tag); 
      message.mTags.put(tag, value); 
     }    
    }   

在Message.toXML中, 「>」 被附加之前,添加:

if (mTags != null) { 
     Iterator<Entry<String, String>> it = mTags.entrySet().iterator(); 
     while (it.hasNext()) { 
      Entry pairs = (Map.Entry)it.next(); 
      String tag = (String) pairs.getKey(); 
      String value = (String) pairs.getValue(); 
      buf.append(" ").append(tag).append("=\"").append(value).append("\""); 
     }    
    }   

然後,在應用程序中,在設置數據包處理程序之前,添加所有自定義標記,例如:

 Packet.parseTags.add(ROOMTYPE); 
    Packet.parseTags.add(ROOMNAME); 
    Packet.parseTags.add(CHATTYPE); 

也發送消息之前,添加的東西,如:

 message.mTags.put(ROOMTYPE, "Private"); 
    message.mTags.put(ROOMNAME, UHInterface.liveSessionID); 
    message.mTags.put(MSGTYPE, "Photo"); 
-3

使用Message.setProperty()因爲消息類擴展包。

郵件類中使用method String toXML(), sb.append("<tag_x>").append(String.valueOf(super.getProperty("tag"))).append("</tag_x>");

,並在項目通話

Message.getProperty 
相關問題