CGI or Common Gateway Interface is a means for providing server-side services over the web by dynamically producing HTML documents, other kinds of documents, or performing other computations in response to communication from the user. In this assignment, students who want to interface with the Oracle database using Oracle's Pro*C precompiled language will be using CGI.
Java Servlets are the Java solution for providing web-based services. They provide a very similar interface for interacting with client queries and providing server responses. As such, discussion of much of the input and output in terms of HTML will overlap. Students who plan to interface with Oracle using JDBC will be working with Java Servlets.
Both CGI and Java Servlets interact with the user through HTML forms. CGI programs reside in a special directory, or in our case, a special computer on the network (cgi-courses.stanford.edu), and provide service through a regular web server. Java Servlets are separate network object altogether, and you'll have to run a special Servlet program on a specific port on a Unix machine.
Input to CGI and Servlet programs is passed to the program using web forms. Forms include text fields, radio buttons, check boxes, popup boxes, scroll tables, and the like.
Thus retrieving input is a two-step process: you must create an HTML document that provides forms to allow users to pass information to the server, and your CGI or Servlet program must have a means for parsing the input data and determining the action to take. This mechanism is provided for you in Java Servlets. For CGI, you can either code it yourself, find libraries on the internet that handle CGI input, or use the following example code that we put together for you: cgiparse.c.
Forms are designated within an HTML document by the fill-out form tag:
<FORM METHOD = "POST" ACTION = "http://form.url.com/cgi-bin/cgiprogram"> ... Contents of the form ... </FORM>
The URL given after ACTION is the URL of the CGI program (your program). The METHOD is the means of transferring data from the form to the CGI program. In this example, we have used the "POST" method, which is the recommended method. There is another method called "GET", but there are common problems associated with this method. Both will be discussed in the next section.
Within the form you may have anything except another form. The tags used to create user interface objects are INPUT, SELECT, and TEXTAREA.
The INPUT tag specifies a simple input interface:
<INPUT TYPE="text" NAME="thisinput" VALUE="default" SIZE=10 MAXLENGTH=20> <INPUT TYPE="checkbox" NAME="thisbox" VALUE="on" CHECKED> <INPUT TYPE="radio" NAME="radio1" VALUE="1"> <INPUT TYPE="submit" VALUE="done"> <INPUT TYPE="radio" NAME="radio1" VALUE="2" CHECKED> <INPUT TYPE="hidden" NAME="notvisible" VALUE="5">
Which would produce the following form:
The different attributes are mostly self-explanatory. The TYPE is the variety of input object that you are presenting. Valid types include "text", "password", "checkbox", "radio", "submit", "reset", and "hidden". Every input but "submit" and "reset" has a NAME which will be associated with the value returned in the input to the CGI program. This will not be visible to the user (unless they read the HTML source). The other fields will be explained with the types:
The second type of interface is the SELECT interface, which includes popup menus and scrolling tables. Here are examples of both:
<SELECT NAME="menu"> <OPTION>option 1 <OPTION>option 2 <OPTION>option 3 <OPTION SELECTED>option 4 <OPTION>option 5 <OPTION>option 6 <OPTION>option 7 </SELECT> <SELECT NAME="scroller" MULTIPLE SIZE=7> <OPTION SELECTED>option 1 <OPTION SELECTED>option 2 <OPTION>option 3 <OPTION>option 4 <OPTION>option 5 <OPTION>option 6 <OPTION>option 7 </SELECT>
Which will give us:
The SIZE attribute determines whether it is a menu or a scrolled list. If it is 1 or it is absent, the default is a popup menu. If it is greater than 1, then you will see a scrolled list with SIZE elements. The MULTIPLE option, which forces the select to be a scrolled list, signifies that a more than one value may be selected (by default only one value can be selected in a scrolled list).
OPTION is more or less self-explanatory -- it gives the names and values of each field in the menu or scrolled table, and you can specify which are SELECTED by default.
The final type of interface is the TEXTAREA interface:
<TEXTAREA NAME="area" ROWS=5 COLS=30> Mary had a little lamb. A little lamb? A little lamb! Mary had a little lamb. It's fleece was white as snow. </TEXTAREA>
As usual, the NAME is the symbolic reference to which the input will be bound when submitted to the CGI program. The ROWS and COLS values are the visible size of the field. Any number of characters can be entered into a text area.
The default text of the text area is entered between the tags. Whitespace is supposedly respected (as between <PRE> HTML tags), including the newline after the first tag and before the last tag.
http://asdf.asdf.asdf/asdf?thisinput=default&thisbox=on&radio1=2Everything after the '?' is the query string. You'll see that a number of expressions appear concatenated by & symbols -- each expression assigns a string value to each form object. In this case, the text field named "thisinput" has the value "default", which is what was typed into the field, the checkbox "thisbox" has the value "on", and the radio button group "radio1" has the value "2" (the second button is checked -- note that this is the value I gave it, not a default value. The default is "on").
Let's look at another example from the second form:
http://zxcv.zxcv.zxcv/zxcv?menu=option+4&scroller=option+1&scroller=option+2
The menu has option 4 selected, and the scroller has option 1 and option 2 selected. Note that spaces are converted to '+' symbols in the URL string. The character '+' is converted to its hex value %2B. Other characters similarly converted are & (to %26), % (to %25), and $ (to %24). This conversion is automatic.
Using GET is not recommended, however. Some systems will truncate the URL before passing it to the CGI program, and thus the QUERY_STRING environment variable will contain only a prefix of the actual query string. Instead, you should use the POST method.
The POST query string is encoded in precisely the same form as the GET query string, but instead of being passed in the URL and read into the QUERY_STRING variable, it is given to the CGI program as standard input, which you can thus read using ANSI functions or regular character reading functions. The only quirk is that the server will not send EOF at the end of the data. Instead, the size of the string is passed in the environment variable CONTENT_LENGTH, which can be accessed using the normal stdlib.h function:
char *value; int length; value = getenv("CONTENT_LENGTH"); sscanf(value, "%d", &length);
Decoding the data is thus just a question of walking through the input and picking out the values. These values can then be used to determine what the user wants to see.
We have written a very simple, linear-search-based mechanism for parsing the input string. These are located, as mentioned above, at cgiparse.c. You might want to cut and paste these into your own code or to use the .h file provided. You can use this in your CGI programs by calling Initialize() at the beginning of your code, and then calling GetFirstValue(key) and GetNextValue(key) to retreive the bindings for each of the FORM parameters. See the comments in the file for more details.
Java handles GET and POST slightly differently. The parsing of the input is done for you by Java, so you are separated from the actual format of the input data completely. Your program will be an object subclassed off of HttpServlet, the generalized Java Servlet class for handling web services.
Servlet programs must override the doGet() or doPost() messages, which are methods that are executed in response to the client. There are two arguments to these methods, HttpServletRequest request and HttpServletResponse response. Let's take a look at a very simple servlet program, the traditional HelloWorld (this time with a doGet method):
import java.io.*; import java.text.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class Hello extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); String title = "Hello World"; out.println("<title>" + title + "</title>"); out.println("</head>"); out.println("<body bgcolor=white>"); out.println("<h1>" + title + "</h1>"); String param = request.getParameter("param"); if (param != null) out.println("Thanks for the lovely param='" + param + "' binding."); out.println("
"); out.println("