2011-06-17 11 views
10

Używam interfejsu API Smack w Javie do łączenia się z moim serwerem XMPP.Jak wysłać niestandardowy pakiet XML za pomocą interfejsu API Java Smack?

Chcę wysłać paczkę niestandardową wiadomość tak:

<message to="[email protected]" type="chat" MYFIELD="custom stuff"> 
    <body> hi </body> 
    <CUSTOM_STANZA A="..." B="..."> 
     C="..." 
     D="..." 
    </CUSTOM_STANZA> 
</message> 

Zgaduję, że tworzę realizować własne pakiet o które zwraca się w ten XML to metoda toxml(). Ale to nie działa.

Każda pomoc zostanie doceniona.

+0

jako [wspomnianym przez Robin] (http://stackoverflow.com/a/6390037/194894): Nigdy nie dodawać atrybutów niestandardowych do góry elementy Stanza poziomu. Zobacz także [XEP-134] (http://xmpp.org/extensions/xep-0134.html#xmpp). Często popełniany jest błąd. – Flow

+0

Nie ma znaczenia, dlaczego tak jest. NIGDY NIE NALEŻY ZROBIĆ! – Robin

Odpowiedz

1

Trzeba zdefiniować klasę niestandardową to powinno implementuje ExtensionElement (jak zapowiadane przez @Flow)

bardzo szczegółowe wyjaśnienie, które produkuje następujące zwrotka jest dostępny in this answer

<message id='923442621149' type='chat'><body>shanraisshan</body> 
<reply xmlns='shayan:reply' rText='this is custom attribute'/> 
</message> 

gdzie odpowiedź jest rozszerzeniem zwyczaj, który zawiera

  1. Element (odpowiedź)
  2. Przestrzeń nazw (shayan: reply)

lista domyślnych nazw XMPP dostępne są w Official XMPP website

+0

Nie, klasa niestandardowa powinna zaimplementować rozszerzenie ExtensionElement – Flow

+2

@ Flow zmieniło moją odpowiedź. Dzięki! – shanraisshan

2

Do tego celu można użyć packet extension: niestety nie ma dobrej dokumentacji ani przykładów użycia rozszerzeń pakietów. Wcześniej patrzyłem na this unresolved question, który ma przykładowy kod, ale nie byłem w stanie go uruchomić: nie mam wyjątków, ale po prostu nie zadziałało, ponieważ moje rozszerzenie nie zostało wywołane i przeszedłem do kodowania moich danych w ciele wiadomości.

EDYCJA: dla potomności, udało mi się uzyskać następujący kod działa. Używa klas DOM4J: DocumentHelper i Element.

Presence np, packet = new Presence(); 
     packet.setID(sessionManager.nextStreamID().toString()); 
     packet.setFrom(server.createJID(operator, null)); 
     if(!available) packet.setType(Presence.Type.unavailable); 
     else packet.setType(null); 

     // add the custom XML 
     Element xml = DocumentHelper.createElement(QName.get("custom", "http://www.custom.com/xmpp")); 
     xml.addAttribute("type", "presenceupdate"); 
     packet.addExtension(new PacketExtension(xml)); 

Lekko humorystyczny: Pobiegłem do mojego własnego odpowiedź rok później, podczas gdy faktycznie próbuje rozwiązać ten problem dla prawdziwego projektu (w przeciwieństwie do majsterkowania jak ja wcześniej), a ponieważ nie mogłem po prostu porzucić to ja musiałem to rozgryźć. Sądzę, że będę potrzebować tej odpowiedzi, więc oto jest. SO: moja pamięć na niebie.

EDIT: Znalazłem jeszcze prostszy sposób to zrobić:

 Element xml = packet.addChildElement("custom", "http://www.custom.com/xmpp"); 
     xml.addAttribute("type", "presenceupdate"); 

Warto zauważyć: próbuje dodać pewne rzeczy (w moim przypadku, próbując dodać opóźnienie elementu) spowodowało w pakiecie nie prowadzony. Coś w Openfire połknęło to, więc to jest coś, na co trzeba uważać.

+0

Kiedy dodaję rozszerzenie pakietu, mogę dodać moje '', więc wszystko działa dobrze. Ale naprawdę chcę edytować sekcję wiadomości, aby mieć "MYFIELD =" niestandardowe rzeczy ". Przez całe życie nie mogę wymyślić, jak dostosować ten nagłówek wiadomości do mojego niestandardowego pola. – BinRoot

+0

Openfire wydaje się upuszczać niektóre pakiety z pustymi ciałami. Dodaj trochę tekstu spoza spacji do ciała. –

7

Nie wiem, dlaczego chcesz dodać niestandardowe atrybuty do wiadomości. Będzie to problematyczne dla klienta i może powodować problemy na serwerze, ponieważ nie będzie pasować do schematu dla sekcji wiadomości.

Treść wiadomości z drugiej strony jest łatwa do obsłużenia jako rozszerzenie @Femi. Musisz utworzyć rozszerzenie MyExtension, które rozszerza PacketExtension, a toXML() w tej klasie zwróci twoją niestandardową sekcję.

Można tworzyć i wysyłać wiadomości niestandardową przez:

Message message = new Message(); 
message.addExtension(new MyExtension()); 
chat.sendMessage(message); 

Aby zapoznać się z pokoju, będziemy chcieli zarejestrować provider, które będą tworzyć i powrócić niestandardowej PacketExtension. Powinieneś rzucić okiem na EmbeddedExtensionProvider, ponieważ zajmuje się on analizowaniem tagów, upraszczając proces.

+1

Chciałbym w tym kontekście wskazać http://xmpp.org/extensions/xep-0134.html#xmpp, co wyjaśnia, dlaczego dodanie niestandardowych atrybutów wiadomości jest złym pomysłem. – Flow

+1

Witam robin, mogę wiedzieć, co to jest nowe MyExtension()? może zapewnić tę klasę – NareshRavva

3

Niedawno dowiedziałem się, jak dodać niestandardową sekcję do wiadomości. Kiedy zorientowałem się, było to dość łatwe. Po prostu musiałem rozszerzyć standardową klasę wiadomości o niestandardową klasę wiadomości.

public class CustomMessage extends org.jivesoftware.smack.packet.Message { 
    public CustomMessage() { 
    super(); 
    } 

    private String customStanza; 

    /** 
    * @param customStanza 
    *   the customStanza to set 
    */ 
    public void setCustomStanza(String customStanza) { 
    this.customStanza = customStanza; 
    } 

    @Override 
    public String toXML() { 
    String XMLMessage = super.toXML(); 
    String XMLMessage1 = XMLMessage.substring(0, XMLMessage.indexOf(">")); 
    String XMLMessage2 = XMLMessage.substring(XMLMessage.indexOf(">")); 
    if (this.customStanza != null) { 
     XMLMessage1 += " CustomStanza=\"" + this.customStanza + "\""; 
    } 

    return XMLMessage1 + XMLMessage2; 
    } 
} 

Następnie użyć niestandardowej klasy do wysyłania wiadomości tak:

CustomMessage message = new CustomMessage(); 
message.setCustomStanza("my data here"); 
System.out.println(message.toXML()); 
muc.sendMessage(message); 

Twoja wiadomość XML będzie wtedy wyglądać tak:

<message id="ee7Y7-8" CustomStanza="my data here"></message> 
+1

To jest najlepsza odpowiedź, aby zrozumieć tworzenie niestandardowej sekcji. Pomógł mi dużo ... Thnx kumple. – Abhishek

+0

Po otrzymaniu końca id nie pokazuje CustomStanza ... –

+4

** Nigdy ** nie ma podklasy "Wiadomość" Smacka. Jeśli uważasz, że musisz to zrobić, robisz coś złego. 'Message' ma być rozszerzony za pomocą [PacketExtension] (https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/packet/PacketExtension.html) – Flow

Powiązane problemy