Java Servlet Programming, 2nd Edition > 2. HTTP Servlet Basics > 2.4 Web Applications |
2.4 Web ApplicationsA web application (sometimes shortened to web app) is a collection of servlets, Java-Server Pages (JSPs), HTML documents, images, templates, and other web resources that are set up in such a way as to be portably deployed across any servlet-enabled web server. By having everyone agree on exactly where files in a web application are to be placed and agreeing on a standard configuration file format, a web app can be transferred from one server to another easily without requiring any extra server administration. Gone are the days of detailed instruction sheets telling you how to install third-party web components, with different instructions for each type of web server. All the files under server_root/webapps/ROOT belong to a single web application (the root one). To simplify deployment, these files can be bundled into a single archive file and deployed to another server merely by placing the archive file into a specific directory. These archive files have the extension .war, which stands for web application archive. WAR files are actually JAR files (created using the jar utility) saved with an alternate extension. Using the JAR format allows WAR files to be stored in compressed form and have their contents digitally signed. The .war file extension was chosen over .jar to let people and tools know to treat them differently. The file structure inside a web app is strictly defined. Example 2-4 shows a possible file listing. Example 2-4. The File Structure Inside a Web Applicationindex.html feedback.jsp images/banner.gif images/jumping.gif WEB-INF/web.xml WEB-INF/lib/bhawk4j.jar WEB-INF/classes/MyServlet.class WEB-INF/classes/com/mycorp/frontend/CorpServlet.class WEB-INF/classes/com/mycorp/frontend/SupportClass.class This hierarchy can be maintained as separate files under some server directory or they can be bundled together into a WAR file. On install, this web application can be mapped to any URI prefix path on the server. The web application then handles all requests beginning with that prefix. For example, if the preceding file structure were installed under the prefix /demo, the server would use this web app to handle all requests beginning with /demo. A request for /demo/index.html would serve the index.html file from the web app. A request for /demo/feedback.jsp or /demo/images/banner.gif would also serve content from the web app. 2.4.1 The WEB-INF DirectoryThe WEB-INF directory is special. The files there are not served directly to the client; instead, they contain Java classes and configuration information for the web app. The directory behaves like a JAR file's META-INF directory: it contains meta-information about the archive contents. The WEB-INF/classes directory contains the class files for this web app's servlets and support classes. WEB-INF/lib contains classes stored in JAR files. For convenience, server class loaders automatically look to WEB-INF/classes and WEB-INF/lib when loading classes no extra install steps are necessary. The servlets in this web app can be invoked using URIs like /demo/servlet/MyServlet and /demo/servlet/com.mycorp.frontend.CorpServlet. Notice how every request for this web app begins with /demo, even requests for servlets. With the Tomcat server, server_root/webapps/ROOT is the default context mapped to the root path "/ ". This means that servlets placed under server_root/webapps/ROOT/WEB-INF/classes can be accessed, as we saw earlier, using the path /servlet/HelloWorld. With Tomcat, this default context mapping can be changed and new mappings can be added by editing the server_root/conf/server.xml serverwide configuration file. Other servers configure mappings in different ways; see your server's documentation for details. The web.xml file in the WEB-INF directory is known as a deployment descriptor . This file contains configuration information about the web app in which it resides. It's an XML file with a standardized DTD. The DTD contains more than 50 tags, allowing full control over the web app's behavior. The deployment descriptor file controls servlet registration, URL mappings, welcome files, and MIME types, as well as advanced features like page-level security constraints and how a servlet should behave in a distributed environment. We'll discuss the contents of this file throughout the book. The full annotated DTD is available in Appendix C.
The structure of the web.xml file is not in itself important at this point; what's important is the fact that having a deployment descriptor file allows configuration information to be specified in a server-independent manner, greatly simplifying the deployment process. Because of deployment descriptors, not only are simple servlets portable, but you can now transfer whole self-contained subsections of your site between servers. Over time it's likely that a commercial market for WAR files will develop. WAR files will become pluggable web components, capable of being downloaded and installed and put to work right away no matter what your operating system or web server. Deployment descriptors also provide web-hosting companies with a convenient way to support multiple customers on the same server. Customers can be given control over their individual domains. They can individually manage servlet registration, URL mappings, MIME types, and page-level security constraints without needing general access to the web server. 2.4.2 The Deployment DescriptorA simple deployment descriptor file is shown in Example 2-5. For this file to describe Tomcat's default web application, it should be placed in server_root/webapps/ROOT/WEB-INF/web.xml. Example 2-5. A Simple Deployment Descriptor<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <servlet> <servlet-name> hi </servlet-name> <servlet-class> HelloWorld </servlet-class> </servlet> </web-app> The first line declares this is an XML 1.0 file containing characters from the standard ISO-8859-1 (Latin-1) charset. The second line specifies the DTD for the file, allowing a tool reading the file to verify the file is valid and conforms to the DTD's rules. All deployment descriptor files begin with these two lines or very similar ones. The rest of the text, everything between <web-app> and </web-app>, provides information to the server about this web application. This simple example registers our HelloWorld servlet under the name hi (surrounding whitespace is trimmed). The registered name is held between the <servlet-name> tags; the class name is placed within the <servlet-class> tags. The <servlet> tag holds the <servlet-name> and <servlet-class> tags together. It's true that the deployment descriptor's XML syntax appears better optimized for automated reading than direct human authoring. For this reason most commercial server vendors provide graphical tools to help the web.xml creation process. There also are several XML editors on the market that help with XML creation.
After this registration, upon restarting the server, we can access the HelloWorld servlet at the URL http://server:8080/servlet/hi. You may wonder why anyone would bother registering a servlet under a special name. The short answer is that it allows the server to remember things about the servlet and give it special treatment. One example of such special treatment is that we can set up URL patterns that will invoke the registered servlet. The requested URL may look to the client like any other URL; however, the server can then detect that the request matches a given pattern mapping and thus should be handled by a particular servlet. For example, we can choose to have http://server:8080/hello.html invoke the HelloWorld servlet. Using servlet mappings in this way can help hide a site's use of servlets. It also lets a servlet seamlessly replace an existing page at any given URL, so all bookmarks and links to the page continue to work. URL patterns are configured using the deployment descriptor, as shown in Example 2-6. Example 2-6. Adding a Servlet Mapping<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <servlet> <servlet-name> hi </servlet-name> <servlet-class> HelloWorld </servlet-class> </servlet> <servlet-mapping> <servlet-name> hi </servlet-name> <url-pattern> /hello.html </url-pattern> </servlet-mapping> </web-app> This deployment descriptor adds a <servlet-mapping> entry indicating to the server that the servlet named hi should handle all URLs matching the pattern /hello.html. If this web app is mapped to the root path "/ ", this lets the HelloWorld servlet handle requests for http://server:8080/hello.html. If the web app is instead mapped to the prefix path /greeting, the Hello servlet will handle requests made to http://server:8080/greeting/hello.html. Various URL mapping rules can be specified in the deployment descriptor. There are four types of mappings, searched in the following order:
When there's a collision between mappings, exact matches take precedence over path prefix matches, and path prefix matches take precedence over extension matches. The default mapping is invoked only if no other matches occur. Longer string matches within a category take precedence over shorter matches within a category. The deployment descriptor snippet in Example 2-7 shows various mappings that can be used to access the HelloWorld servlet. Example 2-7. So Many Ways to Say Hello<!-- ... --> <servlet-mapping> <servlet-name> hi </servlet-name> <url-pattern> /hello.html </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> hi </servlet-name> <url-pattern> *.hello </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> hi </servlet-name> <url-pattern> /hello/* </url-pattern> </servlet-mapping> <!-- ... --> With these mappings, the HelloWorld servlet can be invoked using any of the following list: /servlet/HelloWorld /servlet/hi /hello.html /well.hello /fancy/meeting/you/here.hello /hello/to/you We'll see more practical servlet mappings throughout the rest of the book.
|