Under dessa sidor finns uppgifterna till kursen. Innan uppgifterna presenteras så finns viktig info om allmänna krav och tips.
Det är mycket viktigt att man kan trådning, äpplen och JAR-filer bra så vi börjar med det.
Nivå: | Lätt. |
Allmänt: | Uppgiften går ut på att konstruera ett enkelt multi-trådat program. Det finns två sätt att göra en klass trådad på och vi övar här på båda. Det är mycket viktigt att man förstår båda dessa sätt bra eftersom några av de efterföljande uppgifterna är trådade. Trådning är en mycket vanlig och kraftfull teknik. |
Info: | Kapitel 1 och Lektioner. |
Uppgift: |
Gör ett äpple (med ett grafiskt användargränssnitt) som har två
knappar och en text-area. Respektive knapp ska ha texterna Aktivera utskrift
från tråd 1 och Aktivera utskrift från tråd 2. Använd tre klasser:
Respektive tråd ska i en loop i run-metoden kunna skriva ut meddelandet Utskrift från tråd 1 och Utskrift från tråd 2 i programmets text-area. Utskriften ska göras en gång per sekund. Vid tryck på den ena knappen ska tråd 1 aktiveras och texten på knappen ska ändras till Deaktivera utskrift från tråd 1. Ett tryck till på samma knapp ska deaktivera tråd 1 (det vill säga stoppa tråd 1 helt) och texten på knappen ska återställas till Aktivera utskrift från tråd 1. Motsvarande gäller för den andra knappen men för tråd 2. De färdiga CLASS-filerna ska packas i en JAR-fil och HTML-filen som hör till äpplet ska använda denna JAR-fil. |
Exempel: |
Ett enkelt exempel kan köras från kommandoprompten med:
|
Tips: |
Vid implementering av gränssnittet Runnable så måste man deklarera och initiera en variabel för tråden:
Man måste givetvis även starta tråden (på ett lämpligt ställe) med:
Läs i API-beskrivningen under java.lang.Thread om varför stop-metoden med flera inte fungerar. Där finns bra tips på hur man stoppar en tråd. Man får automatisk scrollning av en JTextArea med:
Man måste göra ett nytt trådat objekt vid varje omstart, det går alltså inte att enbart köra start-metoden igen. |
För den intresserade finns ett mer avancerat multi-trådat program för en enkel grafisk tillämpning, en (för datorn) svår snöstorm, brr :-), där varje snöflinga är en egen tråd. Programmet ställer dock vissa krav på hårdvaran :-). Källkoden finns här.
Nivå: | Lätt. |
Allmänt: | Uppgiften belyser användandet av klassen URL. |
Info: | Kapitel 2, 3 och Lektioner. |
Uppgift: |
Gör ett fristående program med ett grafiskt användargränssnitt
som implementerar en enkel browser. Användaren ska kunna ange en valfri HTTP-adress
i ett text-fält och programmet ska hämta informationen på denna adress och
presentera resultatet i en text-area. Själva hämtningen kan initieras när
användaren trycker på return i text-fältet, på en knapp eller liknande.
När programmet startar ska det hämta och presentera information från den adress som finns default i textfältet från början. Observera! Informationen ska inte tolkas utan bara presenteras som ren text. De färdiga CLASS-filerna ska packas i en JAR-fil och denna ska gå att köra med:
(se manifest). |
Exempel: |
Ett enkelt exempel kan köras enligt följande:
|
Tips: | Använd klassen URL och någon lämplig metod för ett objekt från denna klass, exempelvis metoden openStream vilket returnerar i en in-ström som man kan läsa från. |
I nästa uppgift skall vi bygga en browser som kan tolka den information vi hämtar.
Nivå: | Lätt. |
Allmänt: | Uppgiften visar ett alternativt sätt att bygga en browser på. |
Info: | Kapitel 2, 3 och Lektioner. |
Uppgift: |
Gör samma sak som i Uppgift 2a men med följande modifikationer:
Notera att det nu, av säkerhetsskäl, endast går att göra uppkopplingar till samma domän som äpplet laddades ner från. Mer om detta på kursen Internetsäkerhet. De färdiga CLASS-filerna ska packas i en JAR-fil och HTML-filen som hör till äpplet ska använda denna JAR-fil. |
Exempel: |
Ett enkelt exempel kan köras från kommandoprompten med:
|
Tips: |
Använd klassen javax.swing.JEditorPane (se API-beskrivningen).
Man kan testa sitt äpple under utvecklingen på två sätt. Man kan surfa till:
Försöker man ladda en fil utanför det område beskrivet ovan så genereras en Sequrity Exception. |
För den intresserade så finns ett komplett Java-paket här som man kan använda om man någon gång behöver en ännu mer avancerad browser (som tolkar informationen) i ett Java-program. Det fungerar utmärkt och är mycket lätt att använda.
I Uppgift 2 kopplade vi oss till en speciell typ av server, en HTTP-server, ofta även kallad en webb-server. Vi ska i nästa uppgift koppla oss på ett mer generellt sätt till en server, i detta fall till en chat-server. Vi ska, så att säga, arbeta på en lägre nivå. Detta är ofta mycket användbart och man får mycket större frihet i vad man kan göra. Uppgift 3a och 3b är något svårare men det är mycket viktigt att man kan detta bra.
Nivå: | Medel. |
Allmänt: | Uppgiften belyser användandet av stream sockets på klient-sidan. |
Info: | Kapitel 2, 3 och Lektioner. |
Uppgift: |
Gör ett fristående program med ett grafiskt användargränssnitt
som implementerar en chat-klient som kan sända och ta emot text-meddelanden.
Chat-klienten ska koppla upp sig till en chat-server via en stream-socket.
När en chat-klient sänder ett text-meddelande till chat-servern så sänder
chat-servern detta text-meddelande till alla anslutna chat-klienter. Chat-klienten
ska alltså både kunna:
Chat-klienten ska gå att startas på tre sätt:
Efter detta ska chat-klienten försöka koppla sig till chat-servern. Om kopplingen lyckas så ska det i chat-klientens titelrad stå vilken server och port man är uppkopplad till. Om kopplingen inte lyckas så ska programmet avslutas. De färdiga CLASS-filerna ska packas i en JAR-fil och denna ska gå att köra med:
(se manifest). Verktyget javadoc ska användas för beskrivningen av denna uppgift. |
Exempel: |
Ett enkelt exempel kan köras enligt följande:
Observera! Chat-servern måste vara igång innan man startar chat-klienten, se Uppgift 3a / Tips. Observera! När man använder Netscapes browser för nerladdning så fungerar inte Client.jar och Server.jar. Vi har tyvärr inte löst detta konstiga problem men här finns en ZIP-fil med de viktigaste filerna. |
Tips: |
För att testa klienten kan man antingen:
Använd klassen Socket och metoderna getInputStream och getOutputStream för att få strömmar att läsa och skriva från. Exempel på lämpliga ström-kopplingar:
Klienten måste vara multi-trådad. Hämtningen av meddelanden från servern bör ligga i en evig loop i metoden run. Chat-servern implementerar ett minimalt protkoll som man kan leka med. Om en chat-klient skickar wwhhoo så returnerar chat-servern alla uppkopplade chat-klienters IP-adresser (den inleder svaret med WWHHOO: för varje chat-klient). En chat-klient som utnyttjar detta för att visa uppkopplade chat-klienter är den som används under Hjälp/Chat. Vi har i denna även implementerat ett filter som sorterar ut meddelanden som inte kommer från respektive kurs. |
Det finns en JDK-extension kallad Java Media Framework (JMF) som möjliggör att man kan koppla programmen till datorns mikrofon, kamera, vidoekamera med mera och sända data från dessa saker över nätet (både i klump och streamat). En närmare titt här. Med detta API kan man ju göra enormt intressanta tillämpningar, exempelvis ett video-baserat chat-program.
Nivå: | Svår. |
Allmänt: | Uppgiften belyser användandet av stream sockets på server-sidan. |
Info: | Kapitel 2, 3 och Lektioner. |
Uppgift: |
Gör ett fristående program med ett grafiskt användargränssnitt
som implementerar en chat-server som kan sända och ta emot text-meddelanden.
Chat-servern ska använda stream-sockets. Chat-servern ska kunna ta emot begäran om uppkoppling från nya chat-klienter och placera alla chat-klienter i en egen tråd för att kunna ta emot ytterligare chat-klienter. Varje chat-klient-tråd ligger och väntar på att en chat-klient ska skicka ett text-meddelande. När så sker så ska chat-servern "broadcasta" detta meddelande till samtliga chat-klienter. Chat-servern måste således hålla reda på alla anslutna chat-klienter i någon datasamling. Alla text-meddelanden som sänds från chat-klienterna ska visas en en lämplig swing-komponent, exempelvis en text-area. För samtliga text-meddelanden så ska följande skrivas ut i denna swing-komponent:
Chat-servern ska gå att starta på två sätt:
Efter detta ska chat-servern göra sig redo för att ta emot förfrågningar om anslutning från chat-klienter. Om detta lyckas så ska det i chat-serverns titelrad stå den host och port som chat-servern kör på samt antalet chat-klienter som är uppkopplade. Observera! Chat-servern ska upptäcka när en klient inte längre är ansluten och då ta bort den ur datasamlingen och döda tråden (eventuellt kan tråden döda sig själv). De färdiga CLASS-filerna ska packas i en JAR-fil och denna ska gå att köra med:
(se manifest). Verktyget javadoc ska användas för beskrivningen av denna uppgift. |
Exempel: | Se chat-servern som användes i Uppgift 3a. |
Tips: |
Använd klassen ServerSocket och metoden accept.
Man måste vara försiktig med krockar. Man har ju ofta flera trådar igång för hantering av anslutna chat-klienter och det kan exempelvis bli fel om man samtidigt (1) tar bort en chat-klient-tråd och (2) broadcastar ett meddelande. För att lösa detta bör man deklarera vissa metoder i chat-servern som synchronized. Hur upptäcker chat-servern att en chat-klient har kopplat ner? För varje chat-klient som kopplar upp sig till chat-servern så skapar chat-servern en egen tråd för chat-klienten. Antag att klassen som hanterar chat-klienterna heter ClientHandler. ClientHandler är en tråd som hela tiden ligger och lyssnar på om klienten har skickat något meddelande. Om ett meddelande kommer från en chat-klient så anropar ClientHandler en metod i chat-servern som broadcastar meddelandet till alla anslutna chat-klienter. Det är i denna lyssningsfas som ClientHandler kan upptäcka om en klient har kopplat ner:
Man får då undersöka dessa båda fall och om något av dem uppstår så ska man gå ut ur den "eviga" lyssnar-loopen, exempelvis:
Precis efter try-blocket ligger satserna som stänger alla strömmar, och eftersom de genererar IOException kan de ju lika gärna ligga i try-blocket. Om ett IOException har inträffat tidigare kan man ju antagligen inte stänga strömmarna i alla fall. Exempel på lämpliga ström-kopplingar till klient-socketen:
Hur får man reda på server-socketens host-adress:
Hur får man reda på klient-socketens host-adress:
|
I Uppgift 3 använde vi inget applikationsnivå-protokoll vilket vi ska göra i nästa uppgift. Vi ska även titta på andra typer av intressanta sockets, kallade datagram sockets, samt se hur man använder en mycket bra teknik kallad multicast. Vi ska nu inte använda klient-server paradigmen utan något kallat peer-to-peer, vilket betyder att vi inte längre använder någon central server som knyter samman allt utan allt ligger direkt hos klienterna.
Nivå: | Svår. |
Allmänt: | Uppgiften belyser användningen av datagram sockets och multicast med peer-to-peer paradigmen. |
Info: | Kapitel 2, 3 och Lektioner. |
Uppgift: |
Gör ett fristående program med ett grafiskt användargränssnitt som gör följande:
(1) Text-meddelanden som sänds ska sändas 1 gång per sekund och vara formaterade enligt ett egetkonstruerat protokoll, vi kallar det OTTP, för Online Text Transfer Protocol :-):
Här är:
Det är viktigt att man inte sänder meddelandena oftare än 1 gång per sekund då det i UDP inte finns någon inbyggd "trafikövervakning". Sänder man med UDP för ofta kan nätverket bli överbelastat och gå ner. (2) Text-meddelanden som tas emot ska parsas och för varje namn/host kombination så ska informationen visas på följande format så länge denna användare är uppkopplad:
Endast en rad för varje användare ska visas. De färdiga CLASS-filerna ska packas i en JAR-fil och denna ska gå att köra med:
(se manifest). Efter detta ska programmet koppla sig till multicast-adressen 234.235.236.237 på port 2000. Om kopplingen lyckas så ska det i programmets titelrad stå vilken IP-adress (och port) uppkopplingen skett till. Om kopplingen inte lyckas så ska programmet avslutas. Verktyget javadoc ska användas för beskrivningen av denna uppgift. |
Exempel: |
Ett enkelt exempel kan köras enligt följande:
Kör gärna igång flera program på flera olika datorer. Tänk dock på att multicast är en ny teknik som för nuvarande fungerar bäst i intranät. Vill man använda denna teknik på Internet kan man använda MBone som är ett nätverk av routrar som implementerar olika multicast-protokoll. |
Tips: |
Använd exempelvis fyra klasser:
Har man implementerat detta med flera trådar som möjligtvis delar på någon resurs så kan krockar uppstå och man bör således deklarera vissa metoder som synchronized och/eller använda de synkroniserade datasamlingarna, exempelvis:
I exemplet har dock inget av detta använts. För att dela upp ett inkommet meddelande i enstaka ord så är klassen java.util.StringTokenizer utmärkt. Notera att:
och att det är som det ska, bara att gå vidare med programmeringen :-) Man måste skapa ett nytt DatagramPacket för varje meddelande som ska tas emot. |
Vi har nu bekantat oss med peer-to-peer paradigmen och vet även skillnaden mellan:
Vi vet också att man använder multicast-adresser när man vill sända saker till flera användare. Multicast är bra om vi exempelvis vill sända ut en film från en server till många tittare. Utan multicast så skulle bandbredden som krävs bli direkt proportionell mot antalet användare. Med multicast så blir bandbredden lika stor som för en enda film, oberoende av antalet tittare. En nackdel med multicast är att filmerna måste gå vissa tider, det vill säga, de levereras inte on-demand, men detta kan ju enkelt approximeras genom att sända filmen på olika multicast adresser med vissa tids-intervall.
Nu ska vi titta på ett mycket intressant område som växer enormt fort: XML. XML är ett standard-format för data och det finns många fördelar med detta:
Java och XML är ett perfekt par!
Data givet i XML-form parsas för att kontrollera att formen stämmer enligt XML-standarden. Man kan göra denna kontroll på två sätt:
Man parsar givetvis inte enbart för att kontrollera utan även för att kunna plocka isär och komma åt data i en XML-form. Tekniskt sett, under denna yta, så kan man (för nuvarande) göra parsningen på två sätt:
Vi kommer att använda den utmärkta parsern Xerces. Detta är en av de absolut bästa och stöder både SAX- och DOM-parsning:
The Xerces Java Parser 1.4.2 supports the XML 1.0 recommendation and contains advanced parser functionality, such as support for the W3C's XML Schema recommendation version 1.0, DOM Level 2 version 1.0, and SAX Version 2, in addition to supporting the industry-standard DOM Level 1 and SAX version 1 APIs.
De API för Java 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 icke-intuitiva att använda som Java-programmerare. Vi ska därför använda det allra senaste inom XML: JDOM. JDOM är ett API som ligger ovanpå SAX och DOM och som möjliggör en mycket enklare hantering av XML (med mera). Detta API integrerar mycket väl med Java och de designmönster som Java-programmerare är vana att använda. För samtliga XML-uppgifter är valet fritt om man vill använda SAX- eller DOM-parsning från JDOM.
Nivå: | Lätt. |
Allmänt: | Uppgiften belyser begreppet välutformad XML. |
Info: | Lektioner. Notera att JDOM utvecklas fort och att man för säkerhets skull kontrollerar med tillhörande API-beskrivning för korrekta namn på metoder med mera. |
Uppgift: |
Gör följande:
|
Exempel: |
Ett enkelt exempel kan köras enligt följande:
|
Tips: | Eftersom vi använder en extension till JDK så måste man göra steg 1, 2 och 5 under Exempel ovan. |
Vi ska nu kontrollera om den i Uppgift 5a egengjorda XML-filen är valid utifrån en egengjord DTD-fil.
Nivå: | Lätt. |
Allmänt: | Uppgiften belyser begreppet valid XML samt hur man kommer åt enskilda element och dess barn/värden i en XML-form. |
Info: | Lektioner. |
Uppgift: |
Gör följande:
|
Exempel: |
Ett enkelt exempel kan köras enligt följande:
|
Tips: | Se Uppgift 5a/Tips. |
Vi ska nu titta på hur man skapar XML-former och modifierar dessa direkt i ett program.
Nivå: | Lätt. |
Allmänt: | Uppgiften belyser XML-generering från ett program. |
Info: | Lektioner. |
Uppgift: |
Gör följande:
|
Exempel: |
Ett enkelt exempel kan köras enligt följande:
|
Tips: | Se Uppgift 5a/Tips. |
Till sist ska vi använda det vi nu kan om XML för att skapa en riktig applikation. Den här uppgiften är frivillig men en av de roligaste frivilliga.
Nivå: | Svår. Denna uppgift är frivillig. |
Allmänt: | Uppgiften belyser XML-parsning med validering, XML-generering från ett program och XML-modifikation. |
Info: | Lektioner. |
Uppgift: |
Utgå från chat-klienten i Uppgift 3a för att skapa ett fristående
program med grafiskt användargränssnitt som implementerar en chat-klient
som använder ett protokoll. Detta protokoll skall vara formaterat i XML enligt
filerna message_valid.xml och message.dtd. Programmet ska göra följande:
|
Exempel: |
Ett enkelt exempel kan köras enligt följande:
Programmet startar default mot chat-servern på: atlas.dsv.su.se port: 9494 och vill man använda en chat-server lokalt kan man starta programmet enligt Uppgift 3a samt använda chat-servern från Uppgift 3b. Notera att det ju även kan sändas meddelanden på denna "kanal" som inte följer protokollet i denna uppgift och att man då får meddelandet: KUNDE INTE PARSA ETT MEDDELANDE. |
Tips: |
Man måste vara duktig på paketet java.io för att lösa denna uppgift, exempelvis kan man använda:
för att bygga ett XML-dokument direkt från en String. För att konvertera ett Document till ren text utan radbrytningar är metoden setLineSeparator bra:
|
Nu ska vi titta på hur man kopplar sig till en databas via JDBC. Det här är också mycket roligt :-)!
Nivå: | Svår. Denna uppgift är frivillig. |
Allmänt: | Denna uppgift belyser hur man kopplar sig till en databas-server på Internet. |
Info: | Kapitel 4 och Lektioner. |
Uppgift: |
Gör ett äpple som implementerar en gästbok där användaren ska kunna fylla i följande fält:
Användarens inlägg ska sparas i databas-servern MySQL som kör på atlas.dsv.su.se. Alla inlägg ska visas i en text-area. De färdiga CLASS-filerna ska packas i en JAR-fil och HTML-filen som hör till äpplet ska använda denna JAR-fil. |
Exempel: |
Ett enkelt exempel kan köras från kommandoprompten med:
|
Tips: |
Man behöver här ett JDBC-gränssnitt mot MySQL och det finns i följande zip-fil: twz1.zip. Packa upp zip-filen i katalogen för denna uppgift. Anslutningen görs med:
där:
När man ska skapa en JAR-fil med alla CLASS-filer från filen twz.zip med så gör man enligt följande:
Använd gärna MySQLFront för att få en tydligare bild av vad som sker i databasen. |
Nu tittar vi lite på e-post, vi börjar med sändning.
Nivå: | Svår. Denna uppgift är frivillig. |
Allmänt: | Denna uppgift belyser hur man implementerar sändning av e-post. |
Info: | Lektioner. |
Uppgift: |
Gör ett fristående program med ett grafiskt användargränssnitt som med hjälp av JDK-extensionen Javamail kan sända e-post. Användaren ska kunna skriva in följande:
|
Exempel: |
Ett enkelt exempel kan köras enligt följande:
|
Tips: | Eftersom vi använder en extension till JDK så måste man göra steg 1, 2 och 5 under Exempel ovan. |
Nu fortsätter vi med mottagning.
Nivå: | Svår. Denna uppgift är frivillig. |
Allmänt: | Denna uppgift belyser hur man implementerar mottagning av e-post. |
Info: | Lektioner. |
Uppgift: |
Gör ett fristående program med ett grafiskt användargränssnitt som med hjälp av JDK-extensionen Javamail kan mottaga e-post. Användaren ska kunna skriva in följande:
|
Exempel: |
Ett enkelt exempel kan köras enligt följande:
|
Tips: | Se Uppgift 7a/Tips. |
Vi ska nu, till sist, titta på något verkligt intressant: hur man hos en klient kan använda ett eller flera objekt som egentligen "lever" på ett annat ställe. Hos klienten kan man använda objektet precis som man brukar göra när det "lever" lokalt. Flera olika objekt kan även "leva" på flera olika ställen. Det här är lite krångligt i början men blir snabbt kul!
Nivå: | Svår. Denna uppgift är frivillig. |
Allmänt: | Denna uppgift belyser distribuerade processer med ett exempel där man delar upp ett program i två delar och låter de mer krävande delarna i programmet köra på server-sidan. |
Info: | Kapitel 5 och Lektioner. |
Uppgift: |
Gör ett program som beräknar något krävande på serversidan med hjälp av RMI. Man behöver bara testa detta lokalt på en och samma maskin men det är extra kul om man verkligen kör på två olika maskiner. |
Exempel: |
Ett exempel med Mandelbrots mängd kan köras enligt följande:
|
Tips: | Var väldigt noga och tänk minimalistiskt :-) det blir lätt fel annars. |
Och nu en uppgift för den egna kreativiteten:
Nivå: | Om du är osäker på om din idé till gesällprov är tillräckligt omfattande så skriv e-post hit och fråga. |
Allmänt: | Gesällprovet är ett fritt valt (men obligatoriskt) arbete där du får chansen att visa vad du går för konstruktionsmässigt (istället för minnesmässigt som på en tenta) i "lugn och ro". |
Info: | Se de tidigare uppgifterna. |
Uppgift: |
Följande krav måste uppfyllas:
Med gesällprovet deltar man (frivilligt) i en tävling. De bästa resultaten kommer att presenteras på nätet och vinnaren till första deadline erhåller ett pris. |
Tips: |
Man kan göra ett helt nytt arbete eller bygga vidare på tidigare uppgifter. Några förslag:
Det finns även en rad andra intressanta extensions som vi inte har nämnt tidigare, en bra utgångspunkt för dessa finns här. Använd gärna chat-servern på atlas.dsv.su.se port 9494 för gesällprovet. Huvudsaken är att man gör något som är kul! |
Uppgifterna är gjorda av © Pierre A. I. Wijkman DSV 2001 och är skyddade av lagen om upphovsrätt.