- The Discovery of Water
- The Simplicity of Water
- The Catch
- Conclusion
The Simplicity of Water
Writing an application that serves information via HTTP in other languages is a relatively simple task, but it involves quite a bit more code than is needed in Water. Let's compare a stripped-down HTTP web server written in Java with one written in Water. Listing 1 shows the Java version; Listing 2 shows the Water version. The difference will amaze you.
Listing 1 Java example
// Sample web file server code written in Java // by Mr. Merrick J. Stemen, 2004.04.07 import java.net.*; // Sockets import java.io.*; // Input/Output Streams public class EasyHttp_20040407 extends Thread { public static String root_directory = "."; public static String default_file = "index.html"; Socket incoming; public static void main(String[] argv) { try { ServerSocket ss = new ServerSocket(80); while(true) { EasyHttp_20040407 eh = new EasyHttp_20040407( ss.accept() ); eh.start(); } // end while } // end try catch (Exception e) { System.out.println("Error: " + e); } return; } // Constructor for server instances. public EasyHttp_20040407( Socket incoming ) { this.incoming = incoming; } // Actual server functionality. public void run() { try { BufferedReader data_in = new BufferedReader(new InputStreamReader(incoming.getInputStream())); PrintStream data_out = new PrintStream(incoming.getOutputStream()); String a_request = data_in.readLine(); String[] st = a_request.split(" "); String action_method = null; if(st.length>0) action_method = st[0]; else { incoming.close(); return; } String resource = null; if(st.length>1) { resource = st[1]; if (resource.endsWith("/")) resource = resource + default_file; } else { incoming.close(); return; } if(action_method.equals("GET")) { File fp = new File(root_directory + resource); if(fp.exists()) // If the file exists, get it and respond with it. { FileInputStream br = new FileInputStream(fp); byte[] a_response = new byte[(int)fp.length()]; br.read(a_response); br.close(); data_out.println("HTTP/1.0 200 OK."); data_out.println("Content-type: text/html\r\n\r\n"); data_out.println(); data_out.println(new String(a_response)); } else // If the file does not exist, notify the browser. { data_out.println("HTTP/1.0 404 File Not Found."); data_out.println("Content-type: text/html\r\n\r\n"); data_out.println(); data_out.println("<h1>Error 404: File Not Found."); } } incoming.close(); // Close the connection with the browser. } catch (Exception e) { System.out.println("Error: " + e); } return; // Return from this thread so it will die. } }
Listing 2 Water Implementation
<defmethod get_file file_name="index.html"> <file "logical://user/".<concat file_name /> />.content </defmethod> <server get_file port=8181 />
Water is able to serve the files using fewer lines of code than the Java example in Listing 1 because there are three categories of functions built into Water that Java programmers have to create on their own:
Network service via TCP/IP (sockets)
File I/O
Parsing HTTP commands (String.split())
If I coded all the functionality of the Water server into this Java example, the Java code would grow significantly larger. But because these functions are native to Water applications, the programmer doesn't have to be concerned with these features. Instead, we can concentrate on coding and testing the services, without having to write the code to serve them.