_ 2.1.3 Stream sockets och XML
Uppgiften introducerar till hur man använder XML med stream sockets. Vad är XML och varför är det bra? XML är ett standardformat för data och det finns många fördelar med detta:
- En maskin-människa fördel är att man kan skilja på data och presentation, samma data kan presenteras på olika sätt
- En maskin-maskin fördel är att eftersom allt fler program kommunicerar i olika skikt och har man då en standard för data som sänds mellan dessa program så får man:
== En kontroll av att de data som sänds mellan program uppfyller en viss standard
== Ett enkelt sätt att laborera med data i programmen
== En möjlighet att lätt byta ut program
Data givet i XML-form parsas och man kan göra detta på två sätt:
= Man kontrollerar att data givet i ett XML-dokument följer den generella XML-standard som finns och om ett XML-dokument uppfyller detta krav så kallas det för välutformat
= Man kontrollerar (1) och att det följer vissa direktiv vi själva (eller någon annan) specificerat i en så kallad DTD eller ett XML-Schema och om ett XML-dokument uppfyller detta mer specifika strängare krav så kallas det för valit
Man parsar även för att kunna plocka isär och komma åt data i ett XML-dokument. Tekniskt sett så kan man göra parsningen på två sätt:
- SAX-parsning är snabb och men har inte en fullständig representation av ett XML-dokument i minnet
- DOM-parsning är långsammare men har en fullständig representation av ett XML-dokument i minnet
De API som man använder för dessa två sätt att parsa är anpassade för att fungera med flera olika språk och är ofta ganska svåra och ickeintuitiva att använda som Java-programmerare. Därför finns det andra API:n, som exempelvis [Github: JDOM, https://github.com/hunterhacker/jdom], som ligger ovanpå SAX och DOM och som möjliggör en mycket enklare hantering av XML med Java eftersom de integrerar mycket väl med Java och de designmönster som Java-programmerare är vana att använda.
Java och XML är ett perfekt par för plattformsoberoende processande.
__ Uppgift
Skapa ett program som implementerar en chattklient som använder ett XML-baserat protokoll enligt DTD-filen §[message.dtd, 05_ass/ip1/2/2.1.3/message.dtd]§ för meddelandena, exempelvis:
§
CTTP
1.0
MESS
Pierre A. I. Wijkman
pierre@dsv.su.se
http://dsv.su.se/~pierrre/
unknown
Hejsan!
§
Programmet ska göra följande:
- Vid sändning av meddelanden:
-- Använda klassen §Document§ för att skapa ett XML-dokument som pekar på den publika DTD-filen ovan på adressen §https://atlas.dsv.su.se/~pierre/i/05_ass/ip1/2/2.1.3/message.dtd§ för meddelandet
-- Använda klassen §XMLOutputter§ för att få XML-dokumentet formaterat som en §String§ utan radbrytningar för sändning till chattservern
- Vid mottagning av meddelanden:
-- Använda klassen §SAXBuilder§ för att kontrollera validitet och skapa ett §Document§-objekt
-- Använda detta §Document§-objekt för att accessa de specifika delarna i XML-dokumentet som man sedan ska visa användaren: § (): §
På detta sätt får vi en strikt kontroll av att de meddelanden som sänds och tas emot följer vårt protokoll och att andra program enkelt kan koppla ihop sig med detta system. Gör även:
- En snygg utskrift i kommandoprompten av det XML-dokument som sänds och tas emot
- En felkontroll så att användaren informeras om de meddelanden som inte följer protokollet med utskriften §KUNDE INTE PARSA ETT MEDDELANDE: §
Notera att beskrivningen i denna uppgift är baserad på extensionen [Github: JDOM, https://github.com/hunterhacker/jdom] men att man istället kan använda det i Java inbyggda JAXP om man vill.
__ Exempel
Ett enkelt exempel som använder extensionen [Github: JDOM, https://github.com/hunterhacker/jdom] kan köras enligt följande:
Hämta filen:
- §[XMLChatClient.jar, 05_ass/ip1/2/2.1.3/XMLChatClient.jar]§
Kör programmet med:
- §java -jar XMLChatClient.jar§
Programmet startar default mot chattservern på §atlas.dsv.su.se§ port §9494§ och om man vill använda en egen chattserver lokalt så kan man starta programmet enligt uppgiften [2.1.1 Stream sockets på klientsidan, 05_ass/ip1/2.1.1.txt].
__ Tips
Utgå från programmet i uppgiften [2.1.1 Stream sockets på klientsidan, 05_ass/ip1/2.1.1.txt].
Man kan exempelvis använda följande konstruktion för att bygga ett XML-dokument direkt från §String§-objektet §message§:
§
Document doc = builder.build(new StringReader(message));
§
Eftersom man måste sända hela XML-dokumentet på en rad så behöver man konvertera ett §Document§-objekt till ren text utan radbrytningar och då är metoden §setLineSeparator§ bra:
§
Format format = Format.getCompactFormat();
format.setLineSeparator("");
XMLOutputter xmlOutputter = new XMLOutputter(format);
§
För att visa saker snyggt i kommandofönstret behöver man dock använda ett annat format.
Om man vill använda en enda jar-fil (och slippa hålla på med classpath med mera) så kan man göra enligt följande:
= Packa upp [Github: JDOM, https://github.com/hunterhacker/jdom]: §jar xf jdom.jar§
= Kompilera de egna klasserna: §javac XMLChatClient.java§
= Skapa en manifestfil §mainClass.txt§ (som visar vilken klass som är startklassen) med innehåll: §Main-Class: XMLChatClient§
= Packa ihop allt: §jar cmf mainClass.txt XMLChatClient.jar org *.class§
= Kör med: §java -jar XMLChatClient.jar§
Se vidare:
- [Processing XML with Java, http://www.cafeconleche.org/books/xmljava/]
__ Hjälp
~ 05_ass/help/01.txt
>
[Klicka här för hjälp, helper.dsv@gmail.com, Prog Internet: 2.1.3 Stream sockets och XML: http://atlas.dsv.su.se/~pierre/i/i.cgi?href=05_ass/ip1/2.1.3.txt] ½===system_tutoring_message===½
<
~ 05_ass/help/02.txt