![]() |
CSCI A348/A548Lecture Notes 27 Fall 1999 |
This is going to be an involved assignment. At the end you will have seen a lot of essential Java elements in action, and will have solved in the process your homework 8 assignment and a great deal (more than 90%) of your semester group project. For this project teams could merge, creating larger teams, if you think it helps you.
I start by creating all the code in a directory
That's where I will create the following source code files:/u/dgerman/November/apache_1.3.9/htdocs/hw8
tucotuco.cs.indiana.edu% ls -l total 4 -rw-r--r-- 1 dgerman students 708 Nov 30 12:09 ChatServer.java -rw-r--r-- 1 dgerman students 1254 Nov 30 09:07 HttpChatApplet.java -rw-r--r-- 1 dgerman students 645 Nov 30 10:13 HttpMessage.java tucotuco.cs.indiana.edu% pwd /nfs/paca/home/user1/dgerman/November/apache_1.3.9/htdocs/1201 tucotuco.cs.indiana.edu%Well, all right, then. What do the files contain?
HttpChatApplet.java
looks like this:
Notice how it talks to the server namedimport java.applet.*; import java.awt.*; import java.io.*; import java.net.*; import java.util.*; public class HttpChatApplet extends Applet implements Runnable { TextArea text; Label label; TextField input; Thread thread; String user; public void init() { URL codebase = getCodeBase(); user = getParameter("user"); if (user == null) user = "anonymous"; text = new TextArea(); text.setEditable(false); label = new Label("Say something: "); input = new TextField(); input.setEditable(true); setLayout(new BorderLayout()); Panel panel = new Panel(); panel.setLayout(new BorderLayout()); add("Center", text); add("South", panel); panel.add("West", label); panel.add("Center", input); } public void start() { thread = new Thread(this); thread.start(); } String getNextMessage() { String nextMessage = null; while (nextMessage == null) { try { URL url = new URL(getCodeBase(), "/servlet/ChatServer"); HttpMessage msg = new HttpMessage(url); InputStream in = msg.sendGetMessage(); DataInputStream data = new DataInputStream( new BufferedInputStream( in)); nextMessage = data.readLine(); } catch (Exception e) { try { Thread.sleep(5000); } catch (InterruptedException ignored) { } } } return nextMessage + "\n"; } public void run() { while (true) text.appendText(getNextMessage()); } public void stop() { thread.stop(); thread = null; } void broadcastMessage(String message) { message = user + ": " + message; try { URL url = new URL(getCodeBase(), "/servlet/ChatServer"); HttpMessage msg = new HttpMessage(url); Properties props = new Properties(); props.put("message", message); msg.sendPostMessage(props); } catch (Exception ignored) { } } public boolean handleEvent(Event event) { switch (event.id) { case Event.ACTION_EVENT: if (event.target == input) { broadcastMessage(input.getText()); input.setText(""); return true; } } return false; } }
ChatServer
by using an
object of type HttpMessage
that is exemplified below. (We also
notice that it makes use of the 1.0 (deprecated) version of the AWT but that
can be fixed easily).
Now that we have these two files we can compile the applet, and two classes are going to be created, one for the applet the other one for the helper class (that abstracts HTTP messages). Now we write the servlet:import java.io.*; import java.net.*; import java.util.*; public class HttpMessage { URL servlet = null; String args = null; public HttpMessage(URL servlet) { this.servlet = servlet; } public InputStream sendGetMessage() throws IOException { return sendGetMessage(null); } public InputStream sendGetMessage(Properties args) throws IOException { String argString = ""; if (args != null) { argString = "?" + toEncodedString(args); } URL url = new URL(servlet.toExternalForm() + argString); URLConnection con = url.openConnection(); con.setUseCaches(false); return con.getInputStream(); } public InputStream sendPostMessage() throws IOException { return sendPostMessage(null); } public InputStream sendPostMessage(Properties args) throws IOException { String argString = ""; if (args != null) { argString = toEncodedString(args); } URLConnection con = servlet.openConnection(); con.setDoInput(true); con.setDoOutput(true); con.setUseCaches(false); con.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" ); DataOutputStream out = new DataOutputStream(con.getOutputStream()); out.writeBytes(argString); out.flush(); out.close(); return con.getInputStream(); } private String toEncodedString(Properties args) { StringBuffer buf = new StringBuffer(); Enumeration names = args.propertyNames(); while (names.hasMoreElements()) { String name = (String) names.nextElement(); String value = args.getProperty(name); buf.append(URLEncoder.encode(name) + "=" + URLEncoder.encode(value)); if (names.hasMoreElements()) buf.append("&"); } return buf.toString(); } }
This file contains the source code for three classes. If we compile it we obtain three class files. Once we obtain the bytecode files we move them to theimport java.io.*; import java.net.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class ChatServer extends HttpServlet { MessageSource source = new MessageSource(); public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/plain"); PrintWriter out = res.getWriter(); out.println(getNextMessage()); } public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String message = req.getParameter("message"); if (message != null) broadcastMessage(message); res.setStatus(res.SC_NO_CONTENT); } public String getNextMessage() { return new MessageSink().getNextMessage(source); } public void broadcastMessage(String message) { source.sendMessage(message); } } class MessageSource extends Observable { public void sendMessage(String message) { setChanged(); notifyObservers(message); } } class MessageSink implements Observer { String message = null; synchronized public void update(Observable o, Object arg) { message = (String)arg; notify(); } synchronized public String getNextMessage(MessageSource source) { source.addObserver(this); while (message == null) { try { wait(); } catch (Exception ignored) { } } source.deleteObserver(this); String messageCopy = message; message = null; return messageCopy; } }
servlets
directories and get ready to run the
application. But how do we distribute the clients?
We need to send the applets to the browsers.
So we create three files which differ in only one place.
First we create Larry.html
,
then<html> <applet code=HttpChatApplet codebase=/1201 width=400 height=400> <param name=user value="Larry"> </applet> </html>
Michael.html
,
and finally<html> <applet code=HttpChatApplet codebase=/1201 width=400 height=400> <param name=user value="Michael"> </applet> </html>
Tony.html
:
They differ only in the value of one parameter (the<html> <applet code=HttpChatApplet codebase=/1201 width=400 height=400> <param name=user value="Tony"> </applet> </html>
user
's
name, marked in red
). Now you can
connect to either one of them and participate in the conversation under
one of these three names:
What's left?
You need to