CSCI A348/548
Lab Notes Twelve

Fall 2000


Java networking with Socket class and a bit (more) of CGI.pm
First we look at this feedback collecting script.

#!/usr/bin/perl

use CGI;

$query = new CGI;

if ($query->request_method eq 'GET') {
  &show_form; 
} elsif ($query->request_method eq 'POST') {
  &process_form; 
} else {
  &error('Unsupported request method.'); 
} 

sub error { my ($message) = @_; 
  print $query->header, 

        $query->start_html(-bgcolor=>'white'), 

        qq{ $message }, $query->end_html; 
} 

sub process_form {

  my $email, $message; 

  $message = $query->param('message'); 

  $email = $query->param('email'); 

  $email =~ s/\s//g; 

  if ($email =~ /^[a-zA-Z]+\@indiana.edu$/i) { 
    # do nothing
  } elsif ($email =~ /^[a-zA-Z]+$/i) {
    $email .= "\@indiana.edu"; 
  } else { 
    &error('Unsuported e-mail address format.'); 
    exit; 
  } 

  open MAIL, "| mail $email dgerman\@indiana.edu "; 
  print MAIL $message; 
  close MAIL; 

  print $query->header,
 
        $query->start_html(-bgcolor=>'white'),

        qq{ Your message
$message
has been sent to the webmaster. A copy has been sent to the e-mail address that you indicated. }, $query->end_html; }
sub show_form { print $query->header, $query->start_html(-bgcolor=>'white', -title=>'feedback'), $query->start_form(-method=>'POST', -action=>$query->url), qq{ Email address: }, $query->textfield(-name=>'email', -size=>20, -maxlength=>40), $query->p, qq{Message: }, $query->textarea(-name=>'message', -rows=>5, -columns=>60, -default=>'Replace me with your comments...'), $query->p, $query->submit(-name=>'Proceed'), $query->end_form, $query->end_html; }
As you can see it sends a message to me and to the user of the page, provided that the user has an indiana.edu account. I think you should install this, look at it, and experiment with it. It can help you with the shopping cart. It is taken from lecture notes Eleven.

Next we want to see if we can implement that with Java and to what extent. We start with an .html file to deliver the applet.

<html>
<head><title>Feedback One</title></head>
<body>
  <applet code=Feedback1.class 
          width=400 
          height=400>
  </applet>
</body>
</html>
We put this in Feedback1.html (version 1) in htdocs.

We then write the applet. This first applet is not really a feedback applet, it's just a reminder on how the AWT and event handling work in Java 1.1. Former A202 students should find this very familiar.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Feedback1  extends     Applet 
  implements  ActionListener  {
 
  private Button up, down, left, right; 
  Circle circle = new Circle(100, 100, 30); 
 
  public void init() {
    up    = new Button("Up"   ); 
    down  = new Button("Down" );
    right = new Button("Right"); 
    left  = new Button("Left" );
 
    add(up);     up.addActionListener(this); 
    add(down);   down.addActionListener(this); 
    add(right);  right.addActionListener(this); 
    add(left);   left.addActionListener(this); 
 
  } 
 
  public void actionPerformed(ActionEvent e) {
    Button button = (Button)e.getSource(); 
    if(button == up)          circle.up(); 
    else if (button == down)  circle.down(); 
    else if (button == right) circle.right(); 
    else                      circle.left();            
    repaint(); 
  } 
       
  public void paint(Graphics g) {
    circle.draw(g); 
  }  
       
}
    
class Circle {
  int x, y, radius; 
  Circle (int x, int y, int radius) {
    this.x = x; this.y = y; this.radius = radius; 
  } 
  public void draw(Graphics g) { 
    g.drawOval(x, y, 2*radius, 2*radius); 
  } 
  public void up   () { y -= 3; } 
  public void down () { y += 3; } 
  public void right() { x += 3; } 
  public void left () { x -= 3; } 
}
We then compile and check the result on the web.

Now that we have this running let's make the change in the interface.

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Feedback2  extends     Applet 
                        implements  ActionListener  {
       
  private Button     submit = new Button("Send Comments"); 
  private TextField  nameField = new TextField("", 20); 
  private TextArea   commentsField = new TextArea(5, 45);   
       
  public void init() {
    add(new Label("Name")); 
    add(nameField); 
    add(new Label("Comments"));
    add(commentsField); 
    add(submit); submit.addActionListener(this); 
  } 
       
  public void actionPerformed(ActionEvent e) {
    Button button = (Button)e.getSource(); 
    if (button == submit) {

    } 
  } 
}
Then, of course, we need Feedback2.html:
<html>
<head><title>Feedback Two</title></head>
<body>
  <applet code=Feedback2.class 
          width=400 
          height=400>
  </applet>
</body>
</html>
So now we can check the result online. The interface, though not too spiffy, resembles an HTML form. Let's change actionPerfomed such that when we push the button the text of the message is displayed (while the interface used to collect the data goes away). You will notice that so far you can type in the text field and the text area and even push the button but nothing happens when you push the button.

  public void actionPerformed(ActionEvent e) {
    Button button = (Button)e.getSource(); 
    if (button == submit) {
      String data =     
                       nameField.getText() + "\n" +
                   commentsField.getText() + "\n\n"; 
      mailComments(data); 
      goodBye(data); 
    } 
  }

  void mailComments(String data) {    
    nameField.setEditable(false); 
    commentsField.setEditable(false); 
    submit.setVisible(false); 
  }

  void goodBye(String data) {
    commentsField.setText(
      "Dear " + nameField.getText() + ":\n" + 
      "\nThanks for your comments!\n\n---------------\n" + 
      commentsField.getText()
    ); 
  } 
And the result is here.

Now let's add the code that actually sends the user's comments to the perl script over the network.

import java.io.*;
import java.net.*; 
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Feedback4  extends     Applet 
                        implements  ActionListener  {

  private Button     submit = new Button("Send Comments"); 
  private TextField  nameField = new TextField("", 20); 
  private TextArea   commentsField = new TextArea(5, 45);   

  public void init() {
    add(new Label("Name")); 
    add(nameField); 
    add(new Label("Comments"));
    add(commentsField); 
    add(submit); submit.addActionListener(this); 
  } 

  public void actionPerformed(ActionEvent e) {
    Button button = (Button)e.getSource(); 
    if (button == submit) {
      String data =     
                     nameField.getText() + "\n" +
                 commentsField.getText() + "\n\n"; 
      String cgiData = 
                       "email=" + nameField.getText() 
                     + "&message=" 
                     + commentsField.getText() + "\n\n"; 
       
      mailComments(cgiData); 
      goodBye(data); 
    } 
  }

  void mailComments(String data) {    
    nameField.setEditable(false); 
    commentsField.setEditable(false); 
    submit.setVisible(false); 
    try {
      Socket con = new Socket("burrowww.cs.indiana.edu", 11000);

      BufferedReader in = new BufferedReader(
                            new InputStreamReader(
                              con.getInputStream()));

      PrintWriter out = new PrintWriter(con.getOutputStream(), true); 
      out.println(
        "POST /cgi-bin/fbk HTTP/1.0\r\n" + 
        "Content-type: application/octet-stream\r\n" + 
        "Content-length: " + data.length() + "\r\n\r\n" +
        data
      ); 
      out.flush();


      String read = in.readLine(); 
      while (read != null) {
        System.out.println(in.readLine()); 
      }

      System.out.println("Sent: (" + data.length() + ") " + data);    
      
    } catch (Exception e) {
      System.out.println("E: " + e);
    }
  }

  void goodBye(String data) {
    commentsField.setText(
            "Dear " + nameField.getText() + ":\n" + 
            "\nThanks for your comments!\n\n---------------\n" + 
            commentsField.getText()
            ); 
  } 
}
The interface is unchanged, but the applet now sends the message to the perl script.

Now the last part shows you how you can make a standalone application from an applet (that remains an applet and can still be used as such).

We start by creating an AppletApplication:

import java.applet.*;

class AppletApplication extends Applet {
  public void init() {

  } 
  static void main(String[] args) {
    new AppletFrame(new AppletApplication(), 400, 400); 
  } 
}
To provide a frame we create AppletFrame:
import java.io.*;
import java.net.*; 
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*; 

public class AppletFrame extends Frame implements WindowListener,
                                                  AppletStub, 
                                                  AppletContext   {
  AppletFrame (Applet a, int x, int y) {
    setTitle(a.getClass().getName()); 
    resize(x, y); 
    add("Center", a); 
    a.setStub(this); 
    a.init(); 
    show(); 
    a.start(); 
    addWindowListener(this); 
  } 
  public void windowClosing     (WindowEvent e) { 
    System.exit(0); 
  } 
  public void windowActivated   (WindowEvent e) { } 
  public void windowClosed      (WindowEvent e) { } 
  public void windowDeactivated (WindowEvent e) { } 
  public void windowDeiconified (WindowEvent e) { } 
  public void windowIconified   (WindowEvent e) { } 
  public void windowOpened      (WindowEvent e) { }      

  public boolean       isActive         ()          { return true; } 
  public URL           getDocumentBase  ()          { return null; }  
  public URL           getCodeBase      ()          { return null; } 
  public String        getParameter     (String name) { return ""; } 
  public void          appletResize     (int width, int height)  { } 
  public AppletContext getAppletContext ()          { return this; }  

  public AudioClip     getAudioClip (URL url)       { return null; } 
  public Image         getImage     (URL url)       { return null; } 
  public Applet        getApplet    (String name)   { return null; } 
  public Enumeration   getApplets   ()              { return null; } 
  public void          showDocument (URL url)                  {   } 
  public void          showDocument (URL url, String target)   {   } 
  public void          showStatus   (String status)            {   } 
}
We then use inheritance to create the FeedbackAppletApplication:
public class FeedbackAppletApplication extends FeedbackApplet {
  public static void main(String[] args) {
    new AppletFrame(new FeedbackApplet(), 400, 400); 
  } 
}
You should experiment with this during the lab (if you're done with the chat web application).


Last updated on November 15, 2000, by Adrian German for A348/A548