eng flag In English
bild
Skolan för
datavetenskap
och kommunikation

Laborationer våren 2006

Allmänt

  • Laborationerna kan redovisas för kursansvarig eller kursassistent, men inte för allmänhandledare utan att först kontakta kursledaren. Efter 3 mars kontakta en av dem eller båda.
  • Om du inte labbar på egen dator måste du göra dig bekant med Solaris, antingen genom att köpa ett häfte på CSCs expedition, på Osquars Backe 2, plan 2 (nb), "Introduktion till Unixanvändning på NADA", eller via förre kursledarens lilla introduktion (på engelska)
  • Du kan använda KTelnet för att logga in på godtycklig labbdator på CSC. Det spelar ingen roll vilken, du har ändå tillgång till alla filer. Väl inloggad kan du jobba som i ett vanligt terminalfönster, men du har inte tillgång till det grafiska gränssnittet. Det kan hända att du får problem med att ta bort till vänster om insättningspunkten i emacs, men då får man backa och ta bort framåt i stället.
  • Om du arbetar hemma i Windows och behöver en bra texteditor kan du testa emacs. Titta gärna i den lilla emacskursen (på engelska).
Till överst på sidan »

Labb 1

HTML och Java

Labben utförs ensam eller tillsammans med högst en person.
Deadline: 9 feb 2006

Om du behöver Java för att jobba hemma, se till att ha Java 1.4.2 på Windows)
På Solaris ska du automatiskt få rätt version.

Uppgift 1

Använd inte ett utvecklingssystem eller en HTML-editor utan en vanlig texteditor för att framställa din HTML-sida (emacs eller pico på Mac OS).

För att komma underfund med hur man publicerar HTML-sidor på www ska du göra en enkel HTML-sida med följande innehåll:
Du kan testa att du gjort rätt genom att ladda sidan i en webbläsare.
Sidan ska innehålla text där en del av texten är i fet stil, en annan del i kursiv stil, en del är understruken.
Det ska finnas rubriker både på nivå 1 (största) och nivå 2 (näst största), en länk till en annan sida och en länk till ett annat ställe på den egna sidan (behövs en hel del text för att man ska se effekten).
Det ska finnas en tabell, som inte behöver vara särskilt stor, och en bild.

Du ska publicera din HTML-sida på ditt CSC-konto. För att det ska gå måste det finnas en katalog som heter

public_html
i din login-katalog. Finns det inte kan du skapa den och ge accessrättigheter till den. Du kan använda kommandot:
fs setacl public_html system:anyuser rl
Om din skapade HTML-sida inte ligger i din
public_html
-katalog måste du kopiera den dit och sedan kan du testa genom att starta en webbläsare och skriva in adressen
http://www.student.nada.kth.se/~ditt-login-namn/din-html-sidas-namn.html

Uppgift 2

Skriv ett javaprogram som kan kopiera en fils innehåll till en annan fil. Det ska fungera att skriva:

java Copy orginalfilsnamn destinationsfilsnamn
varvid programmet ska skriva ut:

dagen datum och namnen på orginalfilen och destinationsfilen

och när programmet avslutats ska en kopia av orginalfilens innehåll ha hamnat i destinationsfilen.

Kolla att det blivit rätt genom att på Unix använda kommandot diff och på windows kommandot fc. På Unix skriver man

diff orginalfilsnamn destinationsfilsnamn

Du får inte anta att din orginalfil innehåller text (även om den gör det), det ska gå att köra ditt program på vilken fil som helst.

Tips: Använd inte programmet på dina java-filer. Om du gjort programmet fel kan du förlora dina filer. Så, använd en speciellt hopsatt fil för att testa.

Till överst på sidan »

Labb 2

Sockets, threads, servers

Work alone or in groups no larger than 2 persons. Deadline is feb 10, 2006

Task 1

Connect to a HTTP server and save the file locally.
Use java.net.Socket or java.net.URLConnection to read a file from a HTTP server and save it to the local directory. If you call your class WebGet (and keep the code in WebGet.java), you should invoke your program by either

java WebGet http://someserver/somefile
or
java WebGet serverName fileName
Note! saving the file in the local directory means that you should remove all the path from the file name! e.g. www.nada.kth.se/kurser/kth/2D2052/index.html should be saved as the local file index.html

optional subtask

If the file already exists in the current directory (test that using java.io.File), add a number to its name (e.g. index.html.1, index.html.2 or index1.html, index2.html) until you create a new file name.
Test your program by invoking Unix wget

module add hacks
wget http://someserver/somefile
wget will tell you under what name it saved the file. Then use diff to compare the file brought by wget with the file brought by your program.

Task 2, Optional

Threads: two simple identical threads

Every internet server (in task 3 there will be one) needs to serve more requests at a time so it needs to do more than one thing at a time. For that, Java Threads are used. Run the thread example below (MyRunnable.java). To construct a Thread you need to define a Runnable (basically to define its run() method). Then, to start the Thread, use its start() method.

public class MyRunnable implements Runnable {
   // you will add some more members here

   public void run(){
   // implementing run(), required by the Runnable interface
      while(true){
         System.out.println("this repeats");

         // do not block the CPU, sleep 2 seconds:
         try{
            Thread.currentThread().sleep(2000);
         }
	 catch(InterruptedException ie) {
            ie.printStackTrace();
         }
      }
   }

   public static void main(String[] argv){
      // you will use this twice:
      Runnable r= new MyRunnable();
      Thread t= new Thread(r);
      t.start(); 
   }
}
Stop the running program with Ctrl-c
Extend the code above to start two Threads, one that prints "A" and the other that prints "B", to see the mixed As and Bs printed independently by the threads.
In main(), make two threads (t1 and t2) from two Runnable objects (r1 and r2):
Runnable r1= new MyRunnable("A");
Runnable r2= new MyRunnable("B");
To see that the threads are really independent, use (250 + (long) (Math.random() * 500)) as sleeping time.
This task will be considered completed if you also complete the optional subtask at task 3 below.

Task 3

Reverse server

Based on the examples in the lecture slides, write a server that returns the text you sent to it line by line, but reversed. So if you type a line "abc", it should send back "cba".
The server should only assume that you send text (i.e. you can use readers and writers). To start your server on a port

java ReverseServer port
To test your server, open a telnet connection and type lines into it. You should see them returning to you reversed.
telnet localhost port
Optional task
Task 2 will be considered completed if you make the reverse server multithreaded

Till överst på sidan »

Labb 3

Forms and CGI

Complete this lab in groups of at most 2 persons.
Deadline: 16 feb 2006

Preparation

  • Throughout this lab you will work in your CGI directory /afs/nada.kth.se/public/www.student/cgi-bin/yourUserName
    where youUserName should be replaced by your user name.
    That directory is the proper place for all files you create for the lab
  • If the directory doesn't exist, you do not have a NADA CGI account and you have to ask for one from Delphi. If many of you don't have the account please talk to Serafim.

Task 1

Create a simple HTML form containing the input elements below. See some HTML examples and the HTML standard.
Use a text editor (not a graphic HTML editor) to edit it (e.g. emacs). Save the form in a form.html file in your CGI directory. The form ACTION should be javacgi.sh which you will write at Task 3. Give the page a nice layout and write descriptive labels near each input element. You can test your page by loading it in a web browser using File/Open

Input elements in your form
  1. A text field called "name" where the user should type their name
  2. A textarea called "interests" where the user should type their interests with 4 lines and 80 columns (use ROWS= and COLS= to set the number of lines and columns respectively)
  3. Three chosers (SELECT... OPTION) where the user should enter their birthdate, one called "day" (should show options 1-5), one called "month" (January-April, option values from 1 to 4) and one called "year" (1978-2006). They should only have one line (use SIZE= to set the number of lines in the chooser)
  4. Two radio buttons, both called "gender", one with value "female" and the other one with value "male". The "female" radio button should be checked when you load the page.
  5. A submit button
  6. A reset button

Test your form at http://www.student.nada.kth.se/cgi-bin/yourUserName/form.html
Note: http://www.student.nada.kth.se/cgi-bin/yourUserName/ without a file name will not work! This is because directory listing from browsers is forbidden in NADA's cgi-bin, for security reasons.

Task 2

Make a small CGI that replies to the form. Save it in javacgi.sh. Content is as follows (make sure there is no extra line at the top!):

#!/bin/sh
# This is a simple Unix shell script that
# runs the Java class MyCgiClass
# and passes the $QUERY_STRING enviroment
# variable as a Java "system property"
# which we call arbitrarily "query.string"
/usr/bin/java -Dquery.string=$QUERY_STRING MyCgiClass
If you made your script on Windows and uploaded it to Unix, you are likely to encouter problems (Internal Server Error) due to the different ways of handling newlines on the two operating systems. Try the following:
  • make sure you use "ASCII" FTP transfer
  • if at later steps (below) your script still fails to work, convert newlines to Unix like this:
mv javacgi.sh javacgi.sh.bak; dos2unix javacgi.sh.bak > javacgi.sh
Give the script the necessary execution rights by running this command in your CGI directory:
chmod ugo+x javacgi.sh
Compile MyCgiClass (MyCgiClass.java) below. Look carefully at the code. Don't forget to compile it whenever you change it during Task 3 and 4.
public class MyCgiClass{
  public static void main(String[] ignored){
    // The output of this program will be sent to the browser!
    // so we need to do the HTTP formalities, then we write HTML.
    // First we write the HTTP content-type, then an empty line.
    // After the empty line the browser knows that the HTML begins
    System.out.print("Content-Type: text/html\n\n");

    // Let's write some HTML
    String title= "My first CGI response";
    System.out.println("<HTML><HEAD><TITLE>"+title+");
    System.out.println(</TITLE></HEAD><BODY>");
    System.out.println("<H1>"+title+"</H1>");

    // Read the CGI query string as set by javacgi.sh
    String queryString= System.getProperty("query.string");

    // Print the query string in HTML, nicely preformatted
    System.out.println("<B><PRE>"+queryString+"</PRE></B><BR>");

    // Link back to the form.
    // Note the quote (") escaping as \" in String constants
    System.out.println("Back to <A HREF=\"form.html\">the form</A>");
    System.out.println("</BODY></HTML>");
  }
}

Task 3

Test your CGI Test it in a Terminal window, by setting the QUERY_STRING by hand like this:

cd /afs/nada.kth.se/public/www.student/cgi-bin/yourUserName
setenv QUERY_STRING "month=1&day=2&year=1993&name=John&interests=none"
Now you can run the script as if it would be ran by the WWW server.
./javacgi.sh
When the script works, test it at
http://www.student.nada.kth.se/cgi-bin/yourUserName/form.html
Write stuff in the form and submit the form. See how the query string changes. To check if there are errors, look at
http://cgi.student.nada.kth.se/cgi-bin/get-errlog
Note1:
this is not an efficient way to do CGI in Java, because a Java Virtual Machine taking a huge space in system memory (30 Mb) is started for each http access! You will notice that your CGI access is pretty slow. The correct way to do CGI in Java is to use servlets (Lab 4)
Note2:
you will notice that the query string has spaces replaced by '+', newlines replaced with '%0D%0A', et.c. Every query string needs to be decoded, you don't do that in this lab. Servlets decode the query string for you.

Task 4

Change javacgi.sh and MyCgiClass.java to also print the CGI variable REMOTE_ADDR
Test in the Terminal first, then in the browser (see task 3).

cd /afs/nada.kth.se/public/www.student/cgi-bin/yourUserName
setenv QUERY_STRING "month=1&day=2&year=1993&name=John&interests=none"
setenv REMOTE_ADDR "some.host.on.the.net"
./javacgi.sh

Task 5

Change MyCgiClass.java to also print the "day" CGI parameter. You have the parameter values in the query string so you will need to use some String methods to extract them as substrings:

  • use queryString.indexOf("day=") to find out where the parameter begins
  • use indexOf(stringToLookFor, fromIndex) to find out where the parameter ends
  • once you know where the parameter value begins and ends, use substring(startIndex, int endIndex) to find the value of the parameter
  • .
Test in the Terminal first, then in the browser (see task 3).

Till överst på sidan »

Labb 4

Servlets and JSP

Complete this lab in groups of at most 2 persons.
Deadline: 23 feb 2006

Task 1: My first servlet (code provided)
Task 2: Printing out servlet request parameters and other request data
Task 3: A POST form submission (very easy)
Task 4: My first JSP
Task 5: Session exercise
Task 6: Connecting to a database (code provided)

Preparation

task 1 | task 2 | task 3 | task 4 | task 5 | task 6

APIs used and Documentation
We use Servlet 2.3 and JSP 1.2. Servlet API docs can be found here: servlet package summary and here: servlet http package summary and for JSP here: JSP syntax reference To use servlets, you need either a webserver with servlet support, or a plugin to a web server. In this lab we use Apache Tomcat 5.0. Tomcat can be ran standalone and then it does a webbserver job, or it may be ran with a web server (e.g. Apache). In this lab we use Tomcat standalone.
The servlet programming environment
The servlet programming evironment made for this lab has become a generic NADA tool. Install it in your account (or on your home machine or laptop) as shown in
http://www.sgr.nada.kth.se/unix/docs/localTomcat.html This tool is allmost mandatory as running Tomcat without it is error-prone, as it it easy to make mistakes when setting the environment variables. When ant tomcat and ant compile work correctly you may start with your tasks.

Task 1

prep | task 2 | task 3 | task 4 | task 5 | task 6
1. Copy the form.html that you created in Lab 3 into your localTomcat/webapps/labbar Change the form ACTION to servlet/MyFirstServlet Put the following MyFirstServlet.java in localTomcat/webapps/labbar/WEB-INF/classes (note the differences from MyCgiClass).

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class MyFirstServlet extends HttpServlet {
   public void service (HttpServletRequest req, HttpServletResponse resp)
   throws IOException, ServletException {
      ServletOutputStream out = resp.getOutputStream();

      // Throws IOException, which is already declared
      // in the throws section of this method
      String title= "My second CGI response, a Servlet!";

      out.println("<html><head><title>"+title+"</title></head><body>");

      out.println("<h1>"+title+"</h1>");

      // Read the CGI query string as set by javacgi.sh
      String queryString = req.getQueryString();

      // Print the query string in HTML, nicely preformatted
      out.println("<b><pre>"+queryString+"</pre></b><br>");

      // Link back to the form.
      // Note the quote (") escaping as \" in String constants
      // Since the servlet and the form have different
      // "virtual directories"
      // we need to refer to the form as ../form.html
      out.println("Back to <a href=\"../form.html\">the form</a>");
      out.println("</body></html>");
   }
}
Run ant compile from localTomcat in order to compile the new servlet.
      cd localTomcat
      ant compile
When your servlet compiles correctly, start tomcat
      ant tomcat
Every time you change the servlet, load this page in another browser (not necessary when using JSP!).
http://localhost:8080/manager/reload?path=/labbar
username: student, password: NADA
If tomcat won't stop/start, issue the ps command in the terminal window where you started it and kill the java processes there. Ask the lab assistant for help. Test the form with the new servlet form response at http://localhost:8080/labbar/form.html
Note:
you should see much better performance with servlets than in the case of Java CGIs

Task 2

prep | task 1 | task 3 | task 4 | task 5 | task 6
2. Change MyFirstServlet to print the CGI REMOTE_HOST or REMOTE_ADDR and the value of each CGI parameter (name, interests, day, month, year, gender) in a nice sentence. You can get them all by calling methods of the "req" object. To find which methods you need to call, look at the HttpServletRequest interface and its parent interface ServletRequest.

Task 3

prep | task 1 | task 2 | task 4 | task 5 | task 6
In form.html, change the FORM method to POST (FORM ACTION=... METHOD=POST) and see how the URL changes when you submit. The servlet should continue to work as before (which is not the case for the CGI you did at Lab 3).

Task 4

prep | task 1 | task 2 | task 3 | task 5 | task 6
Copy form.html into form.jsp and test it. It should work as before. Replace the manual generation of the day, month and year choosers with "for" loops in Java scriplets. Display 31 days and all 12 months.

Hint:
      <select name="day" size="1">
      <% for(int i=1; i<=31; i++)  {   %>
            <%--  print a day option instead of this comment --%>
      <% } %>
      </select>
To test if the HTML generated by JSP is what you wanted, look in your browser's menu for "View/Source" or "View/HTML Source".

Task 5

prep | task 1 | task 2 | task 3 | task 4 | task 6
Make MyFirstServlet store the the username in a session attribute. If that session attribute is defined, form.jsp should not display the username INPUT again, but just show the username value instead, by reading from the session. To access the request (and then the session) from JSP, use the pre-defined variable request.
See HttpServletRequest to see how you can create and retrieve a HTTP session, and HttpSession methods. See the "session tracking" example in the servlets.pdf lecture. Test this by submitting the form and going back to form.jsp. When you reload form.jsp, it should not show the username INPUT anymore.

Task 6

prep | task 1 | task 2 | task 3 | task 5 | task 6
A JSP that displays data retrieved from a database of type Mysql

  1. First we need to make sure that the database driver that allows us to connect to the Mysql server is in our web application's WEB-INF/lib directory (that's the servlet/JSP standard place for libraries, e.g. .jar files like below). Execute the following command in one line:
    cp /afs/nada.kth.se/info/intnet03/localTomcat/
    webapps/labbar/WEB-INF/lib/mysql.jar ~/localTomcat/webapps/labbar/WEB-INF/lib/

    If you work at home, download the mysql driver and save it in localTomcat/webapps/labbar/WEB-INF/lib
  2. The database you will connect to has 3 tables
    1. course has 3 fields: id (integer), name (char(255)), and credits (integer, the number of credits)
    2. student has 3 fields: id (integer), name (char(255)), and startyear (integer representing the year when the student started studies)
    3. course_attendance has 5 fields: student_id (integer, foreign key to student.id), course_id (integer, foreign key to course.id), and 3 integers from 3 to 5 representing grades for lab1, lab2 and project. The grade fields may be null, meaning that there are no results for the respective lab/project.
  3. Save the following file in webapps/labbar/database.jsp. Look at it carefully.
    <%@page import="java.sql.*" %>
    <%
       // load the mysql db driver
       Class.forName("com.mysql.jdbc.Driver");
       try{
          // connect to the database
          Connection conn = DriverManager.getConnection(
            "jdbc:mysql://wlab.nada.kth.se/lab",
            "student", "theStudentPassword");
          // issue a query and read the results
          Statement st = conn.createStatement();
          ResultSet result = st.executeQuery("SELECT c.name,
                      c.credits FROM course c");
       %>
       <%-- we open a table, each row in the database
               will be a row in the table --%>
       <table border=1><tr><th>Course name<th>Credits
       <%
          // as long as we have results
          while(result.next()){
             // we write a table row in HTML
       %>
       <%=result.getString(1)%>   <> <%=result.getInt(2)%>
       <%
          // end of while()
          }
          %>
          <%-- end of table --%>
          </table>
          <%
          // end of db connection
          result.close();
          st.close();
          conn.close();
          // end of "try {" above
        } catch(SQLException e){ e.printStackTrace(); }
         %>
    
What you should get from the database:
  • all students, with name and starting year presented in a table
  • show a list of all courses and for each course a table showing the names of the students who took them, and the results for each of lab1, lab2, and project. If there are no results, write "N/A"

Till överst på sidan »

Labb 5

"Client-side" internet programming

Complete this lab in groups of at most 2 persons.
Deadline: 24 feb 2006

XHTML + CSS
Same HTML content using different stylesheets in a frameset
Client-side form validation with Javascript
Simple Applet, opening a URLConnection

Optional but obligatory if you are late: chat server for the simple applet

Preparation

task 1 | task 2 | task 3 | task 4 | task 5
W3 schools
HTML reference
Note that a lot of client-side internet programming can be learned from the pages you like on the Internet by chosing "view source" in your browser. Applets, ActiveX, etc are exceptions.

Task 1

Prep | task 2 | task 3 | task 4 | task 5
Create a XHTML page that has the following:

  1. A cascading style sheet defined externally with the following elements:
  2. h1 as green text, yellow background, extra large, Arial, italic
  3. A class representing centered paragraphs with light-green background
  4. CSS pseudo-classes that make all links in your document change size when you move the mouse over them and must change color when you click on them
  5. At least one example using each of the above
  6. Put the page on the net. XHTML validation should pass

Task 2

Prep | task 1 | task 3 | task 4 | task 5
Write CSS where h1, paragraphs and links are shown however you like, load that in your document instead.
Make a separate xhtml file containing a  frameset that shows the same XHTML content, only with different CSSs.
Add a link from one frame that opens a page in the other  frame (hint).

Task 3

Prep | task 1 | task 2 | task 4 | task 5
Make a FORM that has a TEXT input called "sometext" which you will use Javascript to validate. Your form must not be submitted unless all the conditions below are fulfilled (the submission can go to a non-existent page):
  • the first character of "sometext" is a digit (0..9)
  • the length of "sometext" is equal to that digit
  • It is  better to use Mozilla or a browser that has a Javascript console (Mozilla has it in  Tools/Web development) in order to have some feedback about your Javascript errors.

Task 4

Prep | task 1 | task 2 | task 3 | task 5
Simple applet. Take the simple graphical applet from the lecture
public class SimpleGraphicalApplet extends java.applet.Applet
   implements java.awt.event.ActionListener
{
  java.awt.TextField input= new java.awt.TextField();
  java.awt.TextArea output= new java.awt.TextArea(3, 20);

  /** arrange the two buttons nicely */
  public SimpleGraphicalApplet(){
    output.setEditable(false);
    setLayout(new java.awt.BorderLayout());
    add(input, "North");
    add(output, "Center");
    // we subscribe to listen to action events from the input button
    input.addActionListener(this);
  }

  /** Due to the addActionListener above, this method is called when we press
    Enter on the "input" text field */
  public void actionPerformed(java.awt.event.ActionEvent ignored){
    output.setText(input.getText());
    input.setText("");
  }
}
  • Put a HTML file that uses the applet (see the lecture) in your NADA WWW account. Test the applet in a browser. Whenever you change the  applet, compile it and reload the page. Just reloading the page might fail to reload the applet! In the best case, Shift-Reload may work. If you use Java Plugin, press x in the Java console (press h for other commands). In the worst case, you'll have to restart the browser every time you compile. Maybe then it's better to test it with appletviewer YourFile.html but bear in mind that you will have to test it in the browser in the end because e.g. security constraints (see URL connection below) are not the same in appletviewer and in the browser.
  • Make the applet do the same checks on the text entered is entered on "input" (the first character should be a digit, the length of the text should be the same as that digit indicates). If that's not the case, print an error message in the "output" text area.
  • Let the user type a URL to a HTML file in the input field and print the HTML from that URL into the "output" text area. To accomplish this, construct a java.net.URL and then a  java.net.URLConnection out of it using openConnection(). Connect the URLConnection, then getInputStream() should give you a stream to the HTML content of the URL. To transform that stream content to a String, use either the String(byte,int,int) constructor, or a BufferredReader from which you can get text line by line. To construct a BufferedReader you will need to contruct a reader from an input stream first.
    If there is an exception while connecting to the URL or while retrieving data from it, print the exception's toString() in "output" instead. Optionally, you can also print the exception's toStackTrace().
    Note: due to the applet security restrictions, you will only be able to see HTML coming from the WWW server where the applet was loaded from (e.g. www.student). Otherwise you should see an exception in the "output" text area. Test that!

Task 5

Prep | task 1 | task 2 | task 3 | task 4
Optional, but obligatory if you are late. Make the applet open a Socket. Whatever is entered in "input" will be sent to the socket. Whatever comes from the Socket will be added at the end (appended) to the content of "output". Reading from the socket should be done in a separate Thread. Test your applet by connecting to e.g. the echo port of the WWW server where you store the applet (e.g. www.student)
Write a little chat server for the applet. The server (see lab 2) should keep an array (e.g. Vector) of all OutputStreams  ("talk") to its clients. Whenever something comes from a client (on the "listen" input stream) it should be sent to all these outputstreams.
The server should detect if a client is not connected anymore (catch exceptions when trying to read from or write to it) and delete its OutputStream from the array so it doesn't try to send anything more to that client.

Sidansvarig: <serafim.at.nada.kth.se>
Uppdaterad 2006-03-04