站内搜索: 请输入搜索关键词
当前页面: 图书首页 > JavaServer Pages, Second Edition

JavaServer Pages, Second Edition

[ directory ] Previous Section Next Section

1.3 Solving CGI Problems

The problems of speed, lack of data persistence, and development have all been addressed in a number of ways.

1.3.1 Speeding up CGI

As noted earlier, one of the biggest problems with CGIs is that a whole new program must be started up for every request. A number of approaches have been taken to eliminate this overhead.

One such approach is called Fast CGI. In this model, the CGI remains running instead of restarting each time. The Web server passes the CGI requests to the program over a communication channel called a socket, reads the HTML back over the same channel, and then passes the HTML on to the user. This gives the situation illustrated in Figure 1.3.

Figure 1.3. Fast CGI.

graphics/01fig03.gif

In addition to solving some of the speed problems, this approach also solves the problem of keeping state. Because the CGI program never exits, it can hold onto information between requests. All that is then needed is a way for the CGI to recognize which user is accessing the page, so it will be able to associate the right data with the right user. Typically, this is accomplished by sending the user a cookie, a small marker that the server first sends to the browser and that the browser then includes in any future requests to the same server. Fast CGIs also allow programs to keep connections to a database open, eliminating the need to reopen one for each request. This speeds things up another notch.

Some problems remain with Fast CGIs, however. Most notably, each CGI program is now a separate process, and each will use up a portion of memory and some of the central processor. This can be alleviated by putting the CGIs on a different computer from the one where the Web server lives, but then the sockets must talk across the network, which will slow things down. This will still be faster than having to start a new program each time, so the situation is not all that bad.

Fast CGIs also introduce a new problem. Updating a regular CGI or adding a new one is a pretty simple matter, simply replacing the old version of the program with the new one. Updating a Fast CGI is a bit more involved, as the old version needs to be shut down and the new one started, and the Web server needs to close down the socket and open a new one. Installing a brand new Fast CGI is even more difficult and will typically require some change to the Web server's configuration describing where the Fast CGI process is running and other information. Most Fast CGI implementations will make this process as automated as possible, but it may still require special system privileges to make all the changes happen.

Fast CGIs can be written in C, Perl, or numerous other languages. Typically, the programs look like regular CGIs, with perhaps some additional code at the beginning. This makes it very easy for programmers to learn how to write Fast CGIs, but it leaves all the same problems regarding the intermingling of program code and HTML.

Since the development of Fast CGIs, a few modifications to address these problems have been made. Most of the popular Web servers can address the problem of too many separate processes by allowing new dynamic functionality to be added to the Web server itself. The idea is that new capabilities can be added to the Web server; when it sees a request that it formerly would have passed off to a CGI, the Web server instead invokes the new routines. This greatly enhances the speed of requests, as everything now stays in one process. This architecture is illustrated in Figure 1.4.

Figure 1.4. Web server extensions.

graphics/01fig04.gif

Apache, perhaps the most used and most extensible Web server, took this idea a step further and incorporated the Perl interpreter. This extension, called mod_perl, allows any Perl program, with some minor modifications, to run as part of the Web server.

However, extending the Web server this way is not for the faint of heart! It typically requires a lot of knowledge about the inner details of how the Web server works, as well as very careful programming. If an error causes a CGI to exit prematurely, no harm is done, as the next request will simply start a new one. Even Fast CGIs can typically recover after a crash. But if an extension to the Web server crashes, the whole server is likely to go down.

Updating extensions to the Web server is even more difficult than updating a Fast CGI, and only a few system administrators within any given company will typically have the knowledge and permissions to do so. This makes such an extension useful only for adding very fundamental kinds of functions, such as new registration or security features, and not at all well suited to CGI-like applications.

Another approach to improving performance was taken by application servers. Application servers combine the best features of Fast CGIs and server extensions. Like Fast CGIs, an application server runs as a separate process and stays running between requests. This eliminates the cost of starting a new program each time. Like server extensions, application servers are extensible, allowing programmers to add new features as needed. This architecture is illustrated in Figure 1.5.

Figure 1.5. An application server.

graphics/01fig05.gif

In a sense, application servers can be thought of as enhanced Fast CGIs, whereby each extension acts as a separate Fast CGI, but they all sit in the same process. This has numerous benefits. For example, it was mentioned that a Fast CGI can maintain an open connection to a database. Clearly, though, each Fast CGI running individually will need its own connection. An application server can maintain a central "pool" of open connections and hand one off to each component as needed.

Most modern application servers also support some form of load balancing. This allows multiple instances of an application server to run, possibly on different computers. If one application server gets too busy or one of the computers crashes, all requests can go to another server. The users should never even notice the problem.

1.3.2 Separating HTML from Code

In parallel with the developments on the speed front, progress was made in separating HTML from program logic. The motivation behind many of these approaches can be understood by first considering a very simple CGI and building the complexity up from there.

Consider again Listing 1.1, which is just about the simplest possible CGI. It has almost no logic, except for the two lines needed to get the date and time. Mostly, it prints out a bunch of HTML. Therefore, all the HTML could be pulled out of the CGI and put into a separate file. The CGI would open this file, read the contents, and send them back to the server. The HTML author could then edit the file without needing to touch the program code.

Once this mechanism has been built, it is easy to extend it slowly in order to include such things as the date and time. This is a specific instance of a general problem, namely, that frequently a CGI will have to incorporate some data, such as the date or a user's name, into the page.

However, the HTML author need not care where this data comes from. As far as the design of the page is concerned, the important thing is that the date shows up where it belongs. The HTML author could indicate this by using a special tag, perhaps something like <date/>. If the CGI is written in Perl, this tag could even be a Perl variable, such as the $now variable used in Listing 1.2. Now when it reads the HTML and before sending it to the user, the program can look over the whole file for any occurrences of <date/>, do whatever it needs to in order to get the date, replace the tag with the value, and then send the page along.

This idea can be extended by creating more tags to indicate other common data or behaviors. Essentially, the new tags define a new language that both the programmers and the HTML authors agree to speak, and the CGI acts as a translator, converting tags into actions. This sort of system is often called templating, as the HTML page with the special tags acts as a template, or blueprint, for all the pages built by the CGI.

Unfortunately, this scheme is not quite powerful enough to do all the things dynamic pages need to do. Or rather, by the time it does become sufficiently powerful, the set of tags will be as complicated as any programming language, and we will be back to where we started. Consequently, most systems built around this idea have introduced a few mechanisms that allow this basic scheme to be extended dynamically.

The first is to allow the set of tags to be extensible. An HTML author creating a page for a music catalog, for example, might need a tag to represent the artist's name. In an extensible system, the HTML author could communicate this need to someone in the programming staff, and the two could agree on a new tag to use. The HTML author could then start using this tag while the programmer goes and writes the code that will respond to it.

The system can also be extended in other ways. In addition to creating new tags, the programmers could create new functions, which may be thought of as small magic black boxes, with a slot to drop things into and a ramp where things come out. An HTML author could, metaphorically, drop the name of a musical artist into the slot, and the names of all that artist's albums would come spilling out from the ramp. Then tags could be used to specify where on the page these album names should go.

Best of all, a programmer can extend a templating system like this by providing new objects. In programming terms, objects are much like physical objects in the real world. They have properties that can be obtained or changed, numerous complex ways in which they may relate to other objects, and so on. In the previous example, instead of providing a function, the programmer could provide an "artist" object. One property of this object would be a list of albums, and an HTML-like tag could request this list. Each album would also be an object, and some of its properties would be the year it was recorded, the list of track names, and so on. In other words, the artist object would encapsulate all the relevant information in one neat bundle. Again, tags could be created to access the information from this object and the other objects it contains.

This concept is illustrated in Figure 1.6. The box at the top left displays the list of albums as rendered in a browser. Below this is a simplified view of the "artist" object. The box on the upper right shows a hypothetical page that could generate the data for the browser. First is a tag that sets up the "artist" object with the name of the artist in question; then another tag retrieves the set of albums from the object and sends them to the browser. Although highly simplified, the basic concepts are very similar to the way JSPs work.

Figure 1.6. A tag that uses an object.

graphics/01fig06.gif

New tags, functions, and objects can greatly extend the way the templates get data but still do not allow much control over how that information is presented. For example, it is easy to create a tag that means "get all albums by this artist," but it is much more difficult to express the concept "display all the albums where the first track was written by the lead singer." All the necessary information might be present in the object, but combining that information in arbitrary ways may be infeasible.

Consequently, most templating systems allow for some form of scripting. Scripting allows elements of a full programming language梪sually the language in which the translation CGI is written梩o be included in the page. All languages have a way to compare two pieces of text and do different things, depending on whether they match. The example in the previous paragraph would require writing some code that checked whether the name of the lead signer matched the name of the author of the first track.

This is once again mixing programlike code with HTML, but because most of the hard work is done in the objects or functions, all the HTML authors typically need to know is some relatively simple control structures that do such things as compare two values or loop through a set of values, performing some action on each.

So far in discussing templating, nothing has been said about performance. Not surprisingly, the speed of such a system may be less than ideal. First, the CGI has to be started, then it has to read the template, then it has to look for all the special tags and process them, and so on. All other things being equal, a system like this is likely to be orders of magnitude slower than a CGI written entirely in C.

There is still hope for templating by mixing it with the performance-improvement ideas that were discussed previously. In particular, it is possible to turn the templating CGI into an extension to the Web server, which will eliminate the need to start the CGI up each time a template is needed. This also allows templates to save state information, use shared resources efficiently, and so on. Many such templating systems are alive and well today, from PHP, a well-known hypertext preprocessor that mixes scripting commands with HTML; to WebSQL, a templating system that provides easy access to databases; to osforms, a system built by Object Design to work with its object database.

1.3.3 Servlets and JavaServer Pages

Let's reconsider some of the problems with CGIs. As previously noted, it is time-consuming to have to restart a CGI program for each request. Because the program does not persist between connections, it is difficult to maintain state. Although it is possible to overcome these problems with Fast CGIs or server extensions, these make adding new functionality relatively difficult.

Sun's approach to solving these problems is to use servlets. Just as an applet is a small application that extends the functionality of a Web browser, a servlet is a small piece of code that extends the functionality of a server.

Technically, a servlet is an object, written in Java, that is equipped to receive a request and to construct and send back a response. Because servlets are written in Java, they inherit all the language's power and strengths. One of these strengths is speed, as a great deal of effort has been put into making Java perform well as a server language. Equally important, Java is also a cross-platform technology, so it is possible to develop a servlet under Linux, deploy it on NT, and move to Solaris when the site grows, all without needing to change or recompile anything.

Of special interest to Web developers, Java is an intrinsically dynamic and extensible language. This neatly eliminates the problems inherent in extending a Web server. If it supports Java, the server can be told to load a new servlet with a minimal change to a configuration file and without needing to recompile anything.

The servlet architecture is designed to eliminate the need to reload anything every time a request is made. Instead, the servlet is loaded once, the first time it is needed; after that, it stays active, turning requests into responses as quickly as the Web server can send them. This gives servlets all the speed of Fast CGIs, with none of the hassles. In short, servlets can completely replace CGIs, with no downside.

Servlets also have one additional advantage. Because Java was designed from the ground up as a secure language, servlets can be run in a "secure sandbox," which will prevent them from accessing any potentially sensitive system resources. It is certainly possible to write a CGI that has no security problems, and there are tools to assist in this endeavor. Nonetheless, many security breaches on Web sites happen through insecure CGIs.

The next logical step would be to build a templating system on top of servlets. However, the Art Technology Group (ATG) had an even better idea. Instead of writing a servlet that reads a file, figures out what to do based on special tags, and then does it, why not translate the special tags directly into Java and then compile and run the Java code? This would mean that the first time a page was requested, it would take a little longer to do the conversion, but the second and subsequent requests would be as fast as a servlet. This revolutionary concept, called page compilation, was introduced in ATG's application server, called Dynamo. Sun was so impressed by the concept that it licensed the technology for inclusion in its own Java Web Server. The JHTML model is shown in Figure 1.7.

Figure 1.7. The flow of information through a JHTML page.

graphics/01fig07.gif

No idea is perfect on the first try, and page compilation had problems. Most significantly, there were problems with the set of special tags that ATG had defined, which were somewhat cumbersome, somewhat limited, and completely unlike the tags that other templating systems were using. Over time, Sun has refined these tags to create JavaServer Pages.

JavaServer Pages, or JSPs, combine the best features of the many approaches to dynamic page generation we have discussed. JSPs are implemented in Java, so they are cross platform and inherit all Java's other strengths. Because they are built on top of servlets, JSPs are fast and can be changed easily. They are extensible, and programmers can easily create new objects and functionality using JavaBeans, which page authors can use equally easily.

Sun considers JSPs so important that they are included as a formal part of the Java 2 Enterprise Edition, the standard version of Java for large companies doing complex, performance-critical tasks. Every major vendor of application servers has announced support for JSPs, including ATG, BEA's WebLogic, IBM's Web Sphere, and many more. JSPs have truly become an industry standard.

Best of all, the power of JSPs is not limited to big enterprises or companies that can afford an application server. At the 1999 Java One conference, Sun announced a partnership with the makers of the Apache Web server to provide full support for JSPs under Apache. The resulting project, called Jakarta, has been refined and improved many times since then and now allows anyone with a computer to develop and deploy JSPs梒ompletely for free.

    [ directory ] Previous Section Next Section