The SimpleAPIUsingCGI.pmmodule provides the same functionality as theSimpleAPI.pmand can be run via the http://your_server_name/cgipm_example URL after you add the following lines to htt
Trang 1</body>
</html>
8 As you can see, the embedded PHP script is parsed out and the end user on
the browser side does not even know which database or which user/passwordwas used to produce this page
If you have a lot of pages where you use the same MySQL database to display dataelements using various queries, you should use the include()function to simplifyyour code management tasks For example, Listing 15-12 shows a modified version
of simple_query.phpscript that includes the include()function
$sth = mysql_query(“SELECT * from $table”, $dbh);
while ($myRow = mysql_fetch_row($sth)) {printf(“<tr><td>%s</td><td>%s</td></tr>”, $myRow[0],
Trang 2451Chapter 15 ✦ PHP and Apache
in the header.incfile and be done!
Securing PHP include files
If you use include files, as shown in the last section, to store username, password,and other information, such as database host name, database name, and tablenames, that are not to be seen by users, make sure you keep the include files in asafe directory where Web browsers cannot browse them The best place is outsidethe document tree of the Web site If the document root is /www/mysite/htdocs,then create a directory called /www/mysite/secrets/mysqland keep the includefiles there
If you must create the include files inside the document root, disallow Web browsing
by using the following configuration in httpd.conf:
<Directory /path/to/include_files>
<Limit>
order deny,allowdeny from all
</Limit>
</Directory>
Don’t forget to replace /path/to/include_fileswith the path to the realdirectory of the include files If you keep your include files all over the Web site,you can still disable Web access to them by using the following configurationsegment in httpd.conf:
<Files ~ “\.inc$”>
Order allow,denyDeny from all
</Files>
This will only work if you always make sure all your PHP include files are namedwith the extension inc
Authenticating users with PHP and MySQL
You can use a PHP script to authenticate users via MySQL database Listing 15-13shows a simple script that uses a MySQL database to authenticate users
Note
Trang 3Listing 15-13: auth.php
<?phpob_start();
} else if ((isset($PHP_AUTH_USER)) && (isset($PHP_AUTH_PW))){
$sth = mysql_query(“SELECT 1 from $table WHERE
username = ‘$PHP_AUTH_USER’and
passwd = ‘$PHP_AUTH_PW’”,
$dbh);
$success = mysql_fetch_row($sth);
if ($success[0] == ‘’) {show_challenge();
} else {echo “<P>You’re authorized!</p>”;
# Do something here}
}ob_end_flush();
?>
When this script is requested, it uses the isset()function checks whether twovariables called $PHP_AUTH_USERand $PHP_AUTH_PWare set These two variablesare set by PHP if a user has entered a username and password in response to abasic authentication challenge
Trang 4453Chapter 15 ✦ PHP and Apache
Because the first-time user has not yet seen the authentication challenge dialogbox, these two variables are empty and the show_challenge()function is called
This function simply prints out the BasicHTTP authentication headers, whichforces the Web browser to display a dialog box asking the user to enter a usernameand a password
When the user enters a username and password pair, the pair is sent via theauthentication response header to the Apache server, which is seen by PHP PHPthen sets the $PHP_AUTH_USERand $PHP_AUTH_PWvariables accordingly After thescript is called again automatically in the authentication response request, thescript uses the MySQL database to verify whether or not the username/passwordpair exists If the user credentials (username/password pair) are valid, the scriptdisplays the message “You’re authorized!” and terminates On the other hand, if thecredentials are invalid, the authentication challenge is reissued
Notice that the include(‘/usr/local/apache/htdocs/mysql/header.inc’)call hides all the database connectivity code The header.incfile is shown below:
In the auth.phpscript, notice this line:
$sth = mysql_query(“SELECT 1 from $table
WHERE username = ‘$PHP_AUTH_USER’ andpasswd = ‘$PHP_AUTH_PW’”,
$dbh);
This line performs an SQL query that returns 1if user-supplied credentials (stored in
$PHP_AUTH_USERand $PHP_AUTH_PWautomatically by PHP) matches a usernameand passwdfield, respectively, in the (users) table
Trang 5If your users table has a different field name for username or passwd, make sureyou change the query statement to reflect those names.
The $success = mysql_fetch_row($sth)statement returns an array called
$success, which should have returned the value 1as the first element in
$success[0]if the query is successful Or else the element is undefined
By using the first element $success[0], the decision to display (or not to display)the authentication challenge by using show_challenge()is made
After a user is authenticated, this simple auth.phpscript does not do anythingother than print a message stating that the user was successfully authenticated.You can, of course, have the script do much more than that For example, you canredirect the user to a protected subdirectory by using the Header(“Location:/path/to/subdirectory”);
Note
Trang 6Using Perl with Apache
Aprimary goal of the Apache/Perl integration project was
to bring the full power of the Perl programming languageinto the Apache server This resulted in the development ofmod_perl, which you can compile and link together withApache and Perl to provide an object-oriented Perl interface
to the server’s C language API This enables Perl programmers
to write Apache modules in Perl An Apache-Perl module maystep in during the handler, header parser, URI translation,authentication, authorization, access, type check, fix-up,logger, and cleanup stages of a request
The mod_perlmodule is widely used with Apache to createdynamic contents mod_perlis a very efficient way to usePerl with Apache; you no longer have to run Perl-based CGIscripts, which are slow, resource consuming, and often notsuitable for sites that receive a large number of simultaneousrequests per second This chapter discusses how to compile,install, and configure Apache for mod_perl, how to run yourold CGI scripts by using mod_perl, and how to developmod_perlmodules to take advantage of the Apache API
Compiling and Installing mod_perl
Here is how you can download, compile and install mod_perl
on your system:
1 Download the latest version of the mod_perl source into
the /usr/local/srcdirectory from the http://perl
apache.org/distsite or from an official mirror site
Please make sure you read the installation notes andREADME files in the source distribution before proceedingwith the compilation The steps discussed below mightchange with newer version of mod_perl and/or newerApache
Preloading modulesSharing memoryWriting a databaseapplication inmod_perl
Trang 72 As root, extract the mod_perlsource distribution by using the tar xvzf
mod_perl-version.tar.gzcommand This section assumes that youextracted the Apache source distribution into /usr/local/src
3 Change to the /usr/local/src/mod_perl-version directory and run:
Perl Makefile.PL APACHE_SRC= /apache-version \
DO_HTTPD=1 \USE_APACHE=1 \PERL_MARK_WHERE=1 \EVERYTHING=1
Don’t forget to change /apache-versionwith the appropriate pathname
4 Run the make && make test && make installcommand to compile, test,and install the mod_perl library into the Apache source distribution
5 Change to the Apache source distribution directory and run make installtocompile and install Apache with mod_perl support
6 Start the newly compiled Apache server by using the /usr/local/apache/bin/apachectl startcommand If you are already running a previousversion of Apache server, use the /usr/local/apache/bin/apachectlstopcommand to stop it and then run the start command to relaunch thenew server with mod_perlcapabilities If you’re on a Unix system, you canrun the lynx -dump -head http://localhost/command to dump theheaders that the server displays If mod_perlis installed properly, you willsee mod_perl/versioninformation in the header information
Running CGI Scripts by Using mod_perl
Because CGI scripts are slow and take up more resources under heavy load, in anideal world you will not run CGI scripts when mod_perlis working on your system.However, the reality is that system administrators are busy people and portingsomething that is working already is often ignored because other, more serious,work is awaiting elsewhere Fortunately, mod_perlenables you to run your CGIscripts by using a default mod_perlmodule called Apache::Registry.pm So,you can run your CGI scripts under mod_perlimmediately Here is how
1 In httpd.conffile, create an alias called /apps/to point to your CGI scriptdirectory by adding the following line:
Alias /apps/ “/www/mysite/cgi-bin”
Make sure you change the /www/mysite/cgi-binto whatever is theappropriate CGI script directory on your system
2 Tell Apache to load the Apache::Registrymodule during startup by addingthe following line in httpd.conf:
PerlModule Apache::Registry
Trang 8457Chapter 16 ✦ Using Perl with Apache
3 Tell Apache to run all scripts via Apache::Registryfor the /apps/directory
by adding the following configuration segment in httpd.conf:
<Location /apps>
SetHandler perl-scriptPerlHandler Apache::RegistryOptions ExecCGI
</Location>
4 Restart the Apache server by using the /usr/local/apache/bin/apachectlrestartcommand
5 Access a CGI script using a Web browser by using http://your_server_
name/apps/script_name If you have a ScriptAlias directive setup to point/cgi-bin/to /www/mysite/cgi-bin(or whatever the CGI script directory
on your system is called), then you can access the CGI scripts as “CGI” script
by using http:// your_server_name /cgi-bin/script_name, or you canaccess the same script with mod_perlby using http://your_server_name/
apps/script_name The latter has the advantage of not spawning a newCGI process for each request, enabling it to perform faster Note that themod_perlenvironment variable can distinguish how a script is being run(CGI or mod_perl) Consider, for example, the following code segment:
if ($ENV{MOD_PERL} ne ‘’) {
# Run as mod_perl script as a native mod_perl
# module or Apache::Registry run script} else {
# CGI Script being run via mod_cgi as a
# separate process}
The above conditional statement detects how a script is being run Thescripts in the appsdirectory will be run via the Apache::Registrymodule
This means that you can remove the mod_cgimodule from your systemcompletely by recompiling Apache with disable-module=cgioption
Don’t Reinvent the Wheel
Before you go about writing a cool mod_perlmodule for your Web server, considerlooking around on CPAN for existing modules that might solve your problem As ofthis writing, there are about 500 mod_perl-specific Perl modules on CPAN You canview the available modules on CPAN as follows:
1 Run the perl -MCPAN -e shellcommand
2 At the cpan>prompt, enter i /Apache/ You should receive a list of all theavailable Apache-related modules
Trang 9Creating mod_perl Module By Using the Perl API for Apache
When you installed mod_perlon your system you also installed a very powerful PerlApplication Programming Interface (API) for Apache By using this API, you candevelop mod_perlscripts that take advantage of mod_perlin a “native” way.Although you can run CGI scripts by using mod_perl, they are not designed formod_perlthat uses the Perl API and therefore cannot take full advantage of power
of mod_perl The following material shows how you can develop scripts that arewritten using the Perl API for Apache to take full advantage of the mod_perlmodule
A native mod_perlscript is written as a Perl module with the following architecture:
package MODULE_NAME;
sub handler {
# use the Apache API provided request
# object to do something useful}
sub module_method_1 { # do something useful }sub module_method_2 { # do something useful }sub module_method_3 { # do something useful }
sub module_method_N { # do something useful }1;
Here, the module file starts with a package name The name of the package mustmatch the name of the module file For example, if you name your package (that is,module) as:
perl -le ‘print join(“\n”, @INC)’
You might see output similar to the following:
/usr/lib/perl5/5.6.0/i386-linux/usr/lib/perl5/5.6.0
/usr/lib/perl5/site_perl/5.6.0/i386-linux/usr/lib/perl5/site_perl/5.6.0
/usr/lib/perl5/site_perl
Trang 10459Chapter 16 ✦ Using Perl with Apache
If you use a Perl version other than 5.6.0, then the paths should reflect that Whenmod_perl encounters the first request for a module, it looks at the directories tolocate the module Because it is not a good idea to mix your custom module(s) withthe standard modules provided with Perl and mod_perl, you should create a newdirectory called Developmentin /usr/lib/perl5/site_perland keep yourcustom modules in that directory This enables mod_perlto find your custommodules in the /usr/lib/perl5/site_perl/Developmentdirectory when theyare needed Also, make sure you set the file permissions for this new directory sothat Apache user (set via Userdirective in httpd.conf) can read this directoryand the files within it You can use the following commands to create the newdirectory and to set the file permissions:
mkdir -p /usr/lib/perl5/site_perl/Development
chown -R Apache_User:Apache_Group /usr/lib/perl5/site_perl/Development
chmod -R 750 /usr/lib/perl5/site_perl/DevelpomentDon’t forget to change Apache_Userand Apache_Groupto the appropriate userand group names as set in httpd.conf, by using Userand Groupdirectives,respectively
After you have created a directory, you can create a simple module as shown inListing 16-1 Save this module as /usr/lib/perl5/site_perl/
Trang 11The module name is Development::SimpleAPI This tells mod_perlto load themodule from a subdirectory called Developmentunder any of the directories pointed
to by @INC Because you created the Developmentsubdirectory in the /usr/lib/perl5/site_perldirectory, mod_perlwill load the SimpleAPI.pmmodule fromthis directory This module’s purpose is to demonstrate mod_perlfeatures
This module works as follows:
✦ The use strict; line tells Perl to enforce checking of unsafe constructs This
is a very important line for mod_perlmodules For example, if a variable isused in the script without properly declaring it by using a mystatement, thenPerl will complain about it and force you to declare it before using it
This type of checking is very important because mod_perl modules are loaded inmemory once and run until the server is stopped If one or more unnecessaryvariables are used, the chance of a memory leak occurring might increase
✦ The use Apache::Constants qw(:common);line simply loads theConstants.pmmodule, which defines a set of constants, such as OK,REDIRECT, and DONE, that can be used readily in the script
✦ The next line defines the $callCountervariable and sets it to zero Thisvariable is global to the entire script and its value is available to all invocations
of the script from within the Apache child process Also, note that the variable
is set to zero after when the module is initially loaded
✦ Next, a handler()method is defined This method is given the Apacherequest object ($r) as a parameter, which it uses to write a Content-Typeheader by using the built-in send_http_header()method
Note
Trang 12461Chapter 16 ✦ Using Perl with Apache
✦ The handler()method then prints a minimal HTML document, whichdisplays the Process ID ($$)of the Apache child process and requests acount by using the $callCountervariable The $callCountervariable isincremented afterwards The method returns with an OKstatus and therequest processing terminates
✦ The final line 1;is necessary for Perl modules, which must return a non-zeronumber to qualify as a module
The following steps show how you can run the SimpleAPI.pmmodule
1 First, add the following configuration segment to the httpd.conffile:
# Configuration for running mod_perl modulesPerlModule Development::SimpleAPI
<Location /firstone>
SetHandler perl-scriptPerlHandler Development::SimpleAPI
</Location>
Here’s what’s going on in the above segment:
• The PerlModule directive loads the Development::SimpleAPImodule
at Apache server startup
• The <Location>directive is sets a handler of type perl-scriptforlocation /firstone
• The PerlHandlerdirective tells Apache that the perl-script(that is,mod_perl) handler for the /firstonelocation is the Development::
SimpleAPImodule, which can be found in Development/SimpleAPI.pmfile under a directory pointed to by the @INCarray
2 Restart the Apache server by using the /usr/local/apache/bin/apachectlrestartcommand
3 Run the SimpleAPI.pmmodule for the first time by using the
http://your_server_name/firstoneURL
The request count starts from 0 and goes up if you keep refreshing the page Also,the PID of the Apache child process changes very infrequently To make sure thatyou know how mod_perlmodules work, you must understand that:
✦ During server startup each child process gets shared access to a copy of theSimpleAPI.pmcode This removes the CGI cost (that is, the cost of invoking aCGI script every time it is requested) because the module is already loaded inmemory and is available to each child process and to each child processes’
threads (if any)
Trang 13✦ The first time you access http://your_server_name/firstone, the module
is run for the first time and the $callCountervariable is incremented.Subsequent calls (via your browser’s refresh button) increase the requestcount The count is only increasing for the child process that is servicing yourrequest, however Another child process starts the counter from zero; the
$callCounteris really not shared among the child processes In other words,although the module code is shared among the Apache children, the data isnot shared
✦ Whenever the SimpleAPI.pmmodule is called, Apache passes a requestobject called $rto the handler()method The handler()method acts asthe point-of-entry for the module Code outside the method is only executed
if the hander()method directly or indirectly requires it For example, in thefollowing code, method_one()and method_two()are called becausehandler()requires them:
# something useful}
sub method_two {
# something useful}
✦ The handler()method must return an Apache status code such as OK,DECLINED, DONE, NOT_FOUND, FORBIDDEN, AUTH_REQUIRED, or SERVER_ERROR.You can find a complete list of Apache status constants in the Constants.pmfile supplied with mod_perl Use the locate Constants.pmcommand tolocate the file, or use your system’s file finder utility to locate it On Linuxsystems running Perl 5.6.0, the file path is /usr/lib/perl5/site_perl/5.6.0/i386-linux/Apache/Constants.pm
Using CGI.pm to Write mod_perl Modules
Most people who use Perl with Apache know how to use the CGI.pmmodule forwriting CGI scripts in Perl Thankfully, the CGI.pmauthor realized that people whoare used to using this module might want to still use it in a non-CGI environment
Trang 14463Chapter 16 ✦ Using Perl with Apache
such as mod_perl, so the module’s author made sure that this module is veryusable under mod_perl For example, Listing 16-2 shows a CGI.pmversion of theSimpleAPI.pmmodule, which is now called SimpleAPIUsingCGI.pm
Listing 16-2: A Simple Example that Uses a CGI.pm Module in
a mod_perl Module
package Development::SimpleAPIUsingCGI;
use strict;
use Apache::Constants qw(:common);
use CGI (-compile: all);
Avid CGI.pmdevelopers will notice that I used the -compile: alloption whentelling Perl that I want to use the CGI.pmmodule Here Perl is told to compile allCGI.pmcode once during the initial loading of the module during server startup Thisensures that all CGI.pmfeatures are readily available to the SimpleAPIUsingCGI.pmmodule No more time will be necessary to compile any CGI.pm-specific code during
a request cycle Of course, if you do not use a lot of features of CGI.pm, you can use
Trang 15CGI qw(-compile :standard), or CGI qw(-compile :standard :html3), and so
on, to reduce memory usage by CGI.pmitself Remember that keeping a lot of unusedcode in memory wastes your system resources
Also notice that the CGI object, $query, is created within the handler()method.This is necessary because if you create a CGI object outside the handler()method
in the global section of the module, such as the $callCounter, the object will becreated once for the first request and it will only have that request’s information Forexample, if you move the my $query = new CGI;line outside of the handler()method and place it right after the my $callCounter = 0;line, the script will treateach subsequent request after the initial request as the same request Thus, if youneed to access the query string information using the $query->param()method,you will only get the data for the first request because the $queryobject is notcreated for each request This is why it is very important that you create therequest-specific $queryobject within the handler()method as shown inListing 16-2
The SimpleAPIUsingCGI.pmmodule provides the same functionality as theSimpleAPI.pmand can be run via the http://your_server_name/cgipm_example
URL after you add the following lines to httpd.confand restart the server:
# Configuration for running mod_perl modulesPerlModule Development::SimpleAPIUsingCGI
<Location /cgipm_example>
SetHandler perl-scriptPerlHandler Development::SimpleAPIUsingCGI
</Location>
Preloading Perl Modules to Save Memory
If you use a lot of CPAN modules such as CGIor DBI, or have a lot of developed modules for your Apache server, you might want to use the PerlModuledirective to preload them during server startup Doing so saves time during the firstrequest for such modules and also increases the chances of sharing the code pages(memory) among the Apache child processes For example, if you use the standardCGI, DBI, and Digest::MD5modules in one or more of your mod_perl modules, youcan simply preload these modules by placing the following directives in httpd.conf:
custom-PerlModule CGIPerlModule DBIPerlModue Digest::MD5Another approach is to use the PerlRequiredirective This directive can be set to
an external Perl script that loads all the modules that you want to preload andpossibly share among the Apache child processes For example:
PerlRequire /usr/local/apache/apps/startup.pl
Trang 16465Chapter 16 ✦ Using Perl with Apache
This tells Apache require the /usr/local/apache/apps/startup.plscript duringstartup This script is loaded into memory, which, in turn, should load the necessarymodules For example, this script can be as follows:
#!/usr/bin/perluse CGI ();
If you use all the features of the CGI.pm module you can add CGI->
compile(‘:all’)to the startup.pl script to compile them, which saves timeduring request processing
Also, make sure that the startup.pl scriptis accessible and executable by theApache user (set using Userdirective in httpd.conffile)
Keeping Track of mod_perl Modules
in Memory
Being able to keep track of which mod_perlmodules your Web server is using is agreat help in system administration By using the Apache::Statusmodule thatcomes with mod_perl, you can keep track of loaded modules and get lots ofinformation about them To do so, follow these steps:
1 As root, you must install the prerequisite Devel::Symdumpmodule from aCPAN mirror site by using this command:
perl -MCPAN -e ‘install Devel:Symdump’
2 Add the following configuration segment to the httpd.confbefore any otherPerlModuledirective
PerlModule Apache::Status
<Location /perl-status>
SetHandler perl-scriptPerlHandler Apache::Status
</Location>
This code ensures that the Apache::Statusmodule is loaded before anyother modules If you use the PerlRequiredirective to load modules via anexternal startup script, you do not need the PerlModule Apache::Statusline Instead, load the Apache::Statusmodule in the startup script beforeany other module
Note
Trang 173 Restart the Apache server and access information on loaded mod_perl modules
by using http://your_server_name/perl-status This page displays a list
of options (links), as shown here:
Perl ConfigurationLoaded ModulesInheritance TreeEnabled mod_perl HooksEnvironment
PerlRequired FilesSignal HandlersSymbol Table DumpISA Tree
Compiled Registry Scripts
4 Click on the Loaded Moduleslink to view all the loaded mod_perlmodules.The other links also provide valuable status information on the mod_perlspecifics
Implementing ASP by Using the Apache::ASP Module
Active Server Page (ASP) is a common scripting platform in the Windows world.However, it is no longer a Windows-only scripting platform By using mod_perlwiththe Apache::ASPCPAN module you can create ASP pages that have embeddedPerl-based ASP scripts Here is how:
1 As root, run the following command:
perl -MCPAN -e ‘install Apache::ASP’
The CPAN module installs the Apache::ASPmodule from a local CPAN mirrorsite If it fails for some reason, investigate why and resolve the issues Usuallyinstallation is successful unless you are missing a prerequisite module
In such event, install the missing prerequisite module in the same manner,and then install Apache::ASP
2 After the Apache::ASPmodule is installed, create a subdirectory called asp
in your document root directory I assume that your DocumentRootdirective
is set to /www/mysite/htdocsand that you created the/www/mysite/htdocs/aspdirectory
3 Create a test script called test.aspas shown below and store it in/www/mysite/htdocs/aspdirectory
Trang 18467Chapter 16 ✦ Using Perl with Apache
This simple test.aspASP page simply increments the ASP Application object
by one each time this page is called
4 Add the following lines to the httpd.conffile:
Alias /asp/ “/www/mysite/htdocs/asp”
<Location /asp/>
SetHandler perl-scriptPerlHandler Apache::ASPPerlSetVar Global /tmp
</Location>
Here’s what’s going on in the preceding lines:
• The /asp/alias points to the /www/mysite/htdocs/aspdirectory
Make sure you change this so that it points to appropriate directory inyour system
• The <Location>container tells Apache to use the Apache::ASPmodule
to handle all the files in this directory; it also sets the Globalvariable tothe /tmpdirectory
• The Apache::ASPmodule creates a directory called /tmp/.stateinwhich it stores state information so that even if you shutdown andrestart the server, the state information is not lost
5 Change the file permissions for the aspdirectory and its contents to enableApache user (i.e whatever you set the User directive to in httpd.conf) toaccess the files For example, use the chown -R httpd:httpd /www/mysite/
htdocs/asp && chmod -R 750 /www/mysite/htdocs/aspcommands toensure that Apache user (httpd) and Apache group (httpd) can access thedirectory and files stored in it
6 Restart the Apache server by using the /usr/local/apache/bin/apachectlrestartcommand and access the test.asppage by using
Trang 20Running Java Servlets and JSP Pages with
Tomcat
Over the last few years, Java has become the leading
Web-application platform for enterprise-grade Webdevelopment needs Many large companies refuse toconsider using any platform but Java for Web development
Fortunately, Apache deals with Java quite well Using anApache adapter (module) it can interact with Tomcat, theofficial reference implementation of both Java servlet 2.2 andJSP 1.1 specification
A servlet is a Java program that runs within the Java Virtual
Machine (JVM) on the Web-server system When a request for
a servlet is received, a new thread is created from an loaded servlet Thus, a servlet has a much smaller startuprequirement than does a CGI script Like a CGI program, aservlet can interact with HTTP requests from Web browsers,and with relational databases such as Oracle, Postgres, andMySQL, or with other external applications, and then writeresults in HTTP response A servlet has access to user-supplied data, HTTP headers such as cookies, browserinformation, host information, and so on, just as a CGIprogram does
already-Tomcat, an open -source Java run-time environment (called
a container), for Java servlets, is pretty good at handling
servlet requests, but there is a compromise you can establishbetween Tomcat and Apache You can use an Apache modulecalled mod_jk (it was previously called mod_jserv) to interactwith Tomcat so that Tomcat can be responsible for servingthe servlet requests and Apache can handle everything else
17C H A P T E R
In This Chapter
Installing JDKInstalling TomcatInstalling mod_jkmodule for ApacheConfiguring Tomcatfor Apache
Configuring servletsfor Apache
Configuring yourown servlets or JSPpages
Trang 21Tomcat also implements Java Server Page (JSP) support that allows you to placeJava code in HTML pages with jspextensions Pages with such extensions areparsed by the servlet very similarly to how PHP or ASP pages are parsed Thismakes JSP very similar to PHP or Active Server Pages (ASP) — with the addedadvantages of having the portability of Java and the robustness of the JSPApplication Programming Interface (API) Actually, JSP has all the capabilities ofJava servlets, but it is easier to write Java code for small programming tasks JSPscripts are actually converted automatically into servlets by Tomcat when theyare first referenced, and compiled and instantiated in the servlet container.
This chapter discusses how to make Tomcat and mod_jkwork with Apache so thatyou can use servlets and JSP
If you are not familiar with Java servlets or JSP consider reading a book on thesebefore proceeding with this chapter A detailed discussion of servlet or JSP isbeyond the scope of this book
Why Use Servlets?
The advantages of running servlets versus CGI scripts, or even mod_perl or FastCGIapplications, are:
✦ Servlets are truly platform-independent and therefore highly portable Allmodern server platforms support Java Therefore, deploying servlets in ahybrid network is much easier than any other Web application platform
✦ Fewer overheads than a CGI program because of a smaller startup footprint
No new processes need to be spawned to service a request Simply a newthread is created to service the new request, which has a much smallerresource cost than starting a new process
✦ Database connectivity via Java Database Connectivity (JDBC) is preferable toconnectivity via the Perl DBI, which has major performance issues in high-loadenvironments CGI scripts connect to the database every time they start up;mod_perl scripts can cache database connection but have no good way ofmanaging connections An Apache server running 50 children can potentiallyopen 50 database connections Because high-performance sites have manyWeb servers such database connection requirement alone will be impossible
to manage for most RDBM available today The best approach is connectionpooling which can be done in a mod_perl environment with a great deal ofcustom coding but it is quite simple in a servlet environment
✦ Java servlets run in the Java “send box” (JVM), which makes them moresecure option over other Web application platforms — no more buffer overrun
to worry about
Note
Trang 22471Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
Installing Tomcat
To install Tomcat on your server you need to have a Java Run-time Environment(JRE), and if you plan on developing servlets then you will also need JavaDevelopment Kit (JDK) Also, to use Tomcat with Apache you need the mod_jkmodule In this section I discuss how to install these components to create aTomcat server environment
Installing the latest JDK for Tomcat
Before you install Tomcat, you need an appropriate Java Runtime Environment(JRE) A full software development kit (SDK) is necessary if you’ll be writing andcompiling your own Java servlets The Java Development Kit (JDK), available for freefrom Sun Microsystems (http://java.sun.com/), includes both JRE and developmentpackages You can install JDK for a Linux system by following these steps:
1 Download the latest release version of JDK (that is, SDK) from the official Java
Web site As of this writing the latest version is 1.3 and it is offered as a extracting shell script that creates a binary RPM package You can downloadthe j2sdk-1_3_0_02-linux-rpm.bin(or a later version if available) in adirectory
self-2 As root, run
sh j2sdk-version-linux-rpm.bin
For example, for the 1.3 version you can run:
sh j2sdk-1_3_0_02-linux-rpm.binWhen this script runs it displays a license, which you should say yes to Thescript unpacks and creates an RPM package called j2sdk-version-linux.rpm
(for JDK 1.3 it is j2sdk-1_3_0_02-linux.rpm)
3 Run the rpm -ivh j2sdk-version-linux.rpmto install the JDK For example,
to install the JDK 1.3, run the rpm -ivh j2sdk-1_3_0_02-linux.rpmcommand
4 The JDK is installed in the /usr/java/jdkversion directory For example,the 1.3 JDK is installed in the /usr/java/jdk1.3.0_02directory Thisdirectory is the JAVA_HOMEdirectory You should set up an environmentvariable called $JAVA_HOMEto point to this directory If you use the bashshell, you can set this in your ~/.bashrcfile as follows:
export JAVA_HOME=/usr/java/jdkversionFor example:
export JAVA_HOME=/usr/java/jdk1.3.0_02Enter echo $JAVA_HOMEin your shell prompt to determine whether thisenvironment variable is set If you just added it to the bashrcfile, then youmust run source ~/.bashrcto export the variable
Trang 23If you use a different shell, such as tcsh or csh, use the setenv JAVA_HOME
/usr/java/jdkversioncommand instead of the preceding export command
5 Add the $JAVA_HOMEdirectory in your $PATHenvironment variable using thefollowing line in your ~/.bashrcfile
export PATH=${PATH}:${JAVA_HOME}/binThis line must follow the JAVA_HOMEline discussed in the last step
6 Test the JDK installation by running the java -versioncommand
You should see output similar to the following:
java version “1.3.0_02”
Java(TM) 2 Runtime Environment, Standard Edition (build1.3.0_02)
Java HotSpot(TM) Client VM (build 1.3.0_02, mixed mode)
Installing Tomcat and the mod_jk module
After you have installed the latest release version of JDK from the official Java Website (as described in the last section), you’re ready to install Tomcat and themod_jkmodule as follows:
Download the latest Tomcat binary packages from the official Tomcat Web site athttp://jakarta.apache.org As of this writing the latest release version ofTomcat is 3.2, which will change to 4.0 by the time this book is in the stores
So make sure you change the version numbers mentioned in the instructionsgiven below
For Linux, the latest binary RPM packages can be downloaded from http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.2.1/rpmsdirectory The packages you should download for Linux are:
✦tomcat-version.noarch.rpm(current version: tomcat-3.2.1-1
noarch.rpm) This is the binary distribution of Tomcat
✦tomcat-mod-version.i386.rpm(current version: tomcat-mod-3.2.1-1.i386.rpm) This contains the binary distribution of mod_jkand the oldermod_jservmodules for Apache This will install the mod_jk.somodule in/usr/lib/apachedirectory Because this is an Apache Dynamic SharedObject (DSO) module, you must have Apache compiled with shared objectsupport You can quickly check whether the Apache binary you are runninghas mod_sosupport Run the /usr/local/apache/bin/httpd -lcommand
to list all the modules currently compiled into Apache binary If mod_so.cisnot listed, you need to recompile Apache by using enable-module=sooption in the configure script found in Apache source distribution, and thenrun the make && make installcommand to reinstall Apache with DSOsupport
✦tomcat-manual-version.noarch.rpm(current version: tomcat-manual-3.2.1-1.noarch.rpm) This is the Tomcat document package
Note
Trang 24473Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
Download all of the foregoing files into a temporary new directory and run rpm -ivhtomcat*.rpmcommand from that directory as root to install all the software
By default, Tomcat is installed in /var/tomcatdirectory You need to add thefollowing environment variable in your ~/.bashrcfile:
export TOMCAT_HOME=/var/tomcatLoad the variable in your current shell by running the source ~/.bashrccommand
Configuring Tomcat
In this section I discuss how to configure Tomcat for Apache and how to managesecurity for Tomcat using the Java Security Manager tool
Configuring Tomcat for Apache
The primary configuration file for Tomcat is /var/tomcat/server.xml As you cantell from the extension, it is an XML file
Tomcat can use two types of connection handlers, the Ajp13 and Ajp12 protocols
The Ajp13 protocol is the newer protocol, and provides better performance, andwhich also supports Secure Socket Layer (SSL) connectivity
To activate the Ajp13 protocol-based connection handler in Tomcat, you shouldmake sure that that the following connector configuration is not commented out inserver.xmlfile:
<ConnectorclassName=”org.apache.tomcat.service.PoolTcpConnector”>
<Parameter name=”handler”
value=”org.apache.tomcat.service.connector.Ajp13ConnectionHandler”/>
<Parameter name=”port” value=”8009”/>
</Connector>
The servlet.xml file should already have a block of code similar to the precedingfor Ajp12 connections on port 8007 Even if you plain to use the Ajp13-basedconnector, you should not delete this connector It is required to shut down Tomcat
The properties of a Tomcat instance, called worker, are defined in /var/tomcat/
conf/workers.propertiesfile The default file (without comments) contains theproperties shown in Listing 17-1
Caution
Trang 25Listing 17-1: Default Tomcat (worker) properties
workers.tomcat_home=c:\jakarta-tomcat workers.java_home=c:\jdk1.2.2
ps=\
worker.list=ajp12, ajp13 worker.ajp12.port=8007 worker.ajp12.host=localhost worker.ajp12.type=ajp12 worker.ajp12.lbfactor=1 worker.ajp13.port=8009 worker.ajp13.host=localhost worker.ajp13.type=ajp13 worker.ajp13.lbfactor=1 worker.loadbalancer.type=lb worker.loadbalancer.balanced_workers=ajp12, ajp13 worker.inprocess.type=jni
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)classes worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)jaxp.jar worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)parser.jar
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)jasper.jar worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)servlet.jar worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)webserver.jar worker.inprocess.class_path=$(workers.java_home)$(ps)lib$(ps)tools.jar worker.inprocess.cmd_line=-config
worker.inprocess.cmd_line=$(workers.tomcat_home)/conf/jni_server.xml worker.inprocess.cmd_line=-home
worker.inprocess.cmd_line=$(workers.tomcat_home) worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jv m.dll
worker.inprocess.stdout=$(workers.tomcat_home)$(ps)inprocess.stdout worker.inprocess.stderr=$(workers.tomcat_home)$(ps)inprocess.stderr worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
This default properties file defines an ajp12 worker, ajp13 worker, a jni worker, and
a lb worker The differences among these worker types are shown in Table 17-1
Trang 26475Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
Table 17-1
Differences Among Types of Workers
Worker Type Description
ajp12 This worker uses the ajpv12 protocol to forward requests to
out-of-process Tomcat workers that are using the ajpv12 protocol.
ajp13 This worker uses the ajpv13 protocol to forward requests to
out-of-process Tomcat workers that are using the ajpv12 protocol Because ajpv13 is a newer protocol than ajpv12, the ajp13 type of worker can achieve better performance than can an ajp12 type worker Also, ajp13 offers SSL support.
jni By using the Java Network Interface (JNI) this type of worker can
forward requests to in-process Tomcat workers An in-process worker runs within a JVM opened in Apache’s own memory space.
lb By using a simple round-robin load-balancing scheme, this worker
can forward requests.
The workers.propertiesfile has a few settings that are “global” to all types ofworkers For example:
workers.tomcat_home=c:\jakarta-tomcatworkers.java_home=c:\jdk1.2.2
ps=\
worker.list=ajp12, ajp13These settings are global The first one sets the home directory for Tomcat Thisshould be set to the value of the $TOMCAT_HOMEenvironment variable Because thedefault installation of Tomcat creates /var/tomcatas the directory under Linuxsystem, you should change the default value (c:\Jakarta-tomcat) as follows:
workers.tomcat_home=/var/tomcatSimilarly, the workers.java_homesets the top-level path for the JDK installationdirectory, which under Linux is /usr/java/jdkversion(for example, for JDK 1.3,this is /usr/java/jdk1.3.0_02) So, this should be set as follows:
workers.java_home=/usr/java/jdk1.3.0_02The next line tells Tomcat what separator to use for separating directory elements
The default value \works for Windows system because on Windows platformsdirectory names are separated by using \ On UNIX systems, it should be /
So, set this line as shown here:
ps=/
Trang 28477Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
The final class path (on Linux) for the inprocess worker looks as shown here:
/var/tomcat/classes:/var/tomcat/lib/jaxp.jar:/var/tomcat/lib/parser.jar:/var/tom cat/lib/jasper.jar:/var/tomcat/lib/servlet.jar:/var/tomcat/lib/webserver.jar:/us r/java/jdk1.3.0_02/lib/tools.jar
The next four lines, as shown below, define a set of command-line options for theinprocess worker:
worker.inprocess.cmd_line=-config worker.inprocess.cmd_line=$(workers.tomcat_home)/conf/jni_server.xml worker.inprocess.cmd_line=-home
worker.inprocess.cmd_line=$(workers.tomcat_home)The next line defines the JVM library path:
worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(
ps)classic$(ps)jvm.dllThe JVM library path (on Linux) is/usr/java/jdk1.3.0_02/jre/lib/i386/classic/libjvm.so So you mustchange the above jvm_libline to be:
worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)lib$(
ps)i386$(ps)classic$(ps)libjvm.soThe next two lines define the filenames that are used to write the STDOUTandSTDERRfor the inprocess worker:
worker.inprocess.stdout=$(workers.tomcat_home)$(ps)inprocess
stdoutworker.inprocess.stderr=$(workers.tomcat_home)$(ps)inprocess
stderrThe STDOUTis written to /var/tomcat/inprocess.stdoutand STDERRis written
to /var/tomcat/inprocess.stderron a Linux system
The final line defines a system property for the inprocess worker The defaultproperty set by the following line is tomcat.homewith the value /var/tomcat
on Linux:
worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
Configuring Tomcat to use the Java Security Manager
The Java Security Manager enforces security restrictions on everything Java, whichincludes applets, servlets, JSP, and even Tomcat itself By using the Java SecurityManager, you can control what each application can or cannot do Table 17-2 showsthe types of permissions you can set
Trang 29Table 17-2
Java Security Manager Permission Types
Permission Type Meaning
java.util.PropertyPermission Controls read/write access to JVM properties such
as java.home.
java.lang.RuntimePermission Controls use of some system or run-time
functions such as exit() and exec().
java.io.FilePermission Controls files and directories permissions java.net.SocketPermission Controls use of network sockets.
java.net.NetPermission Controls use of multicast network connections java.lang.reflect Controls use of reflection to do class
ReflectPermission introspection.
java.security Controls access to security methods.
SecurityPermission java.security.AllPermission Allows everything, which is effectively same thing
as not using the Java Security Manager.
The security policies for Tomcat are defined in /var/tomcat/conf/tomcat.policyfile This file typically grants permissions using the following syntax:
grant codeBase code_source { permission_type class [name [, action_list]];
grant codeBase “file:${tomcat.home}/webapps/examples” {permission java.net.SocketPermission “localhost:1024-”,
Trang 30479Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
If you want an application called /var/tomcat/webapps/your_app_nameto connect
to the Lightweight Directory Access Protocol (LDAP) server using TCP port 389, thegrant permission that you need is:
grant codeBase “file:${tomcat.home}/webapps/ app_name” {
permission java.net.SocketPermission “localhost:389”,
1 In /var/tomcat/conf/server.xmlfile you should find the following:
<! Uncomment out if you have JDK1.2 and want to use policy
<ContextInterceptorclassName=”org.apache.tomcat.context.PolicyInterceptor” />
>
This default setting disables the Security Manager, so you must remove thecomments so that you have the following instead:
<ContextInterceptorclassName=”org.apache.tomcat.context.PolicyInterceptor” />
2 Restart Tomcat using the -securityoption For example, /usr/bin/tomcat-securityrestarts Tomcat with Java Security Manager
The JVM will throw an AccessControlExceptionor a SecurityExceptionwhen the Java Security Manager intercepts a security policy violation
Configuring Apache for Servlets and JSP
When you start Tomcat, it creates a configuration file called /var/tomcat/conf/
mod_jk.conf-auto You need this file to be loaded by Apache to interact withTomcat To do so, modify httpd.confto add the following line:
Include /var/tomcat/conf/mod_jk.conf-autoThe automatically generated mod_jk.conf-autofile has one problem It instructsApache to load the mod_jk.somodule from a subdirectory called libexecunder theserver’s root directory (pointed to by ServerRootdirective in httpd.conf)
Unfortunately, this directory does not exist and mod_jk.sois installed in /usr/lib/
apachedirectory So, you have two choices:
Trang 31✦ Instead of pointing to /var/tomcat/conf/mod_jk.conf-autofile by usingthe Includedirective, you can copy this file with another name (for example,mod_jk.conf) and use:
Include /var/tomcat/conf/mod_jk.confYou then modify the mod_jk.conffile to have the LoadModule jk_modulelibexec/mod_jk.soline changed to LoadModule jk_module
/usr/lib/apache/mod_jk.so
✦ Or, you can simply create a subdirectory called libexecwithin your Apacheserver root directory and put mod_jk.soin it In this case, you must startApache after starting Tomcat because the /var/tomcat/conf/mod_jk.conf-autois generated by Tomcat every time it starts
I assume that you made the first choice, which is more manageable The very firstconfiguration line is:
LoadModule jk_module /usr/lib/apache/mod_jk.soThe LoadModuledirective loads the mod_jk.soDSO module that enables Apache
to interact with Tomcat
JkWorkersFile /var/tomcat/conf/workers.propertiesThis line sets the JkWorkersFiledirective to point to /var/tomcat/conf/workers.properties, which provides mod_jkwith the needed information toconnect to the different tomcat instances, which are also called workers Leave thisdirective alone
JkLogFile /var/tomcat/logs/mod_jk.logHere the log file path is defined using the JkLogFiledirective
JkLogLevel errorThe above line sets the log level for recording errors in log files Possible log levelsare debug, warn, error, and emerg, but warnshould be your default selection
JkMount /*.jsp ajp12JkMount /servlet/* ajp12The two lines shown above assign /*.jspand /servlet/*URL prefixes tothe Tomcat worker called asp12 This means that any URL request that has/<anything>.jps(for example, /foo.jsp, /bar.jsp) or /servlet/<anything>(for example, /servlet/foo, /servlet/bar) will be assigned to the asp12 worker
It is recommended that you change these two lines so that the worker is asp13(faster) instead, as shown here:
JkMount /*.jsp ajp13JkMount /servlet/* ajp13
Trang 32481Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
The directives shown here are typical Apache directives:
Alias /examples “/var/tomcat/webapps/examples”
The next two directives, as shown below, assign /examples/servlet/*and/examples/*to Tomcat worker asp12:
JkMount /examples/servlet/* ajp12JkMount /examples/*.jsp ajp12You can change them to asp13 if you wish It is not critical because these are simplyexamples
The next group of directives, as shown below, disables access to the WEB-INFandMETA-INFOdirectories under the examplestree These two directories should not
be browseable, so this measure is appropriate:
<Location “/examples/WEB-INF/”>
AllowOverride Nonedeny from all
</Location>
<Location “/examples/META-INF/”>
AllowOverride Nonedeny from all
</Location>
The next group of directives, as shown below, creates exactly the same configuration
as was created for /examples
Alias /admin “/var/tomcat/webapps/admin”
</Location>
<Location “/admin/META-INF/”>
Trang 33AllowOverride Nonedeny from all
</Location>
Feel free to change the worker for /admin/servlet/*and /admin/*.jspto ajp13
to take advantage of this new, faster protocol Finally, the same configuration isrepeated for /test:
Alias /test “/var/tomcat/webapps/test”
</Location>
<Location “/test/META-INF/”>
AllowOverride Nonedeny from all
</Location>
After you have finished modifying the previous configuration and have saved thehttpd.conffile, restart the Apache server You can access the servlet and JSPexamples by using http://your_web_server/examples/ You can also access theadmintool by using http://your_web_server/admin/ However, if you to viewcontexts (that is, virtual directory) information using the Web-based admintool,you must create a user called adminin /var/tomcat/conf/tomcat-users.xmlfile This file looks like this:
<tomcat-users>
<user name=”tomcat” password=”tomcat” roles=”tomcat” />
<user name=”role1” password=”tomcat” roles=”role1” />
<user name=”both” password=”tomcat” roles=”tomcat,role1” />
</tomcat-users>
In the following example, I have added a user called adminwith a password mypwd
<tomcat-users>
<user name=”tomcat” password=”tomcat” roles=”tomcat” />
<user name=”role1” password=”tomcat” roles=”role1” />
<user name=”both” password=”tomcat” roles=”tomcat,role1” />
<user name=”admin” password=”mypwd” roles=”admin” />
</tomcat-users>
Trang 34483Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
With this user, you can view the contexts via the Web interface if you enable thetrusted = truefor the admin context as shown below:
to trusted at all time opens your server to serious security risks For example, whenthe admin context is trusted (by setting trusted=”true”) you can create a contextvia http://your_server_hostname/adminthat exposes your entire filesystem tothe Web To exploit this, a cracker needs a Tomcat system with admin context set
to trusted and the plain-text XML file /var/tomcat/conf/tomcat-users.xmlwith
an admin username and password The best way to deal with this is to remove theadmin context completely, or at least to make sure that you have this set tountrusted (that is, trusted=”false”)
Working with Tomcat
After you have configured Tomcat you can start working with it In this section
I show you how to disable Tomcat’s default Web service (on port 80) that is meant
to serve static pages because Apache does a better job of serving static pages
I then show you how to start and stop the Tomcat server and lastly I discuss a shellscript that can be used to automate Tomcat startup process
Disabling Tomcat’s default HTTP service
By default, Tomcat services HTTP requests on port 8080 However, after you haveApache and Tomcat integrated using the mod_jk.somodule, it is unnecessary tohave Tomcat service HTTP requests on port 8080 You can fix this in the followingsection of the /var/tomcat/conf/server.xmlfile:
<! Normal HTTP >
<ConnectorclassName=”org.apache.tomcat.service.PoolTcpConnector”>
<Parameter name=”handler”
value=”org.apache.tomcat.service.http.HttpConnectionHandler”/>
Trang 35<Parameter name=”handler”
value=”org.apache.tomcat.service.http.HttpConnectionHandler”/>
<Parameter name=”port”
value=”8080”/>
</Connector>
*** DISABLED Normal HTTP Service on Port 8080 >
Starting and stopping Tomcat
Before you can start or stop Tomcat, you must make sure that environment variablessuch as $JAVA_HOMEand $TOMCAT_HOMEare set and that the $PATHvariable has the
$JAVA_HOME/binpath in it You can use the echocommand to check whether thesevariables are set already in your shell If you have followed the installation sectionsabove you should have these variables set in your ~/.bashrcfile
If you have these environment variables set, you can simply run the /usr/bin/tomcat startcommand or the tomcatclt startcommand to start Tomcat.You can use the /usr/bin/tomcat stopcommand to stop it You can also runthe/usr/bin/tomcat runcommand to run it in the foreground Running it in theforeground is only recommended for troubleshooting when you need to see Tomcaterror messages on the console
Starting Tomcat with a shell wrapper script
It very useful to create the necessary environment in a shell script and run thesecommands using a shell wrapper script called /usr/bin/tomcatctl, which isshown in Listing 17-2 This saves a lot of typing and helps avoid mistyping errors
Note
Trang 36485Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
# end
After this script is stored in /usr/binand you have enabled execute permission byrunning the chmod 755 /usr/bin/tomcatctlcommand, you can start or stopTomcat without worrying about the environment variables For example, to startTomcat you can run the tomcatctl startcommand; to stop run the tomcatctlstopcommand; and to run it in the foreground, run the tomcatctl runcommand
The binary RPM package also installs the /etc/rc.d/init.d/tomcatscript
This script is symbolically linked to the appropriate run-level so that Tomcatautomatically starts and stops every time you reboot the system However, thedefault value for JAVA_HOMEand for the JDK path in /etc/rc.d/init.d/tomcatmight not be appropriate for everyone For example, the default values set in thisscript for these two variables are shown below:
export PATH=$PATH:/opt/IBMJava2-13/bin:/opt/IBMJava2-13/jre/bin export JAVA_HOME=/opt/IBMJava2-13
These appear to be the RPM developer’s own settings If you followed my earlierinstructions to download the JDK from Sun Microsystems’s Web site, yourinstallation path for the JDK will differ So, be sure to modify these two settings
in/etc/rc.d/init.d/tomcatscript For example, the correct values are:
export PATH=$PATH:/usr/java/jdk1.3.0_02/bin:/usr/java/jdk1.3.0_02/jre/bin export JAVA_HOME=/usr/java/jdk1.3.0_02
Running Java servlets
In this section I discuss how you can set up Tomcat to run the example servletsthat are shipped with it, and I show you how you to run your own servlets or JSPpages that you have developed or downloaded from the Internet
Trang 37Never run Tomcat as root Create a new user and group called tomcat and changethe file and directory permissions for /var/tomcat by using the chmod -R 755/var/tomcatcommand.
Running Java example servlets via Tomcat
To run Java servlets, you do not need Apache You can use Tomcat, which is an
open -source Java run-time environment called a container, for Java servlets.
Tomcat can be installed in parallel to your Web server and it can service both staticand servlet requests However, Tomcat is much less versatile when it comes toconfiguration and serving static requests It is simply not a replacement for thehighly configurable Apache Web server If you want to use Tomcat, though, thissection’s for you
By default, when Tomcat is started it services servlet requests from port 8080.After you’ve started Tomcat, you should be able to access example servlets andJSP pages using http://localhost:8080if you are running the Web browser
on the Tomcat server Or, you can access it from another machine using thehttp://your_web_server_hostname:8080/ When you access the defaultTomcat server, the page looks similar to Figure 17-1
Figure 17-1: The default Tomcat server page.
Click on the JSP Examples link and you will see a page as shown in Figure 17-2
Caution
Trang 38487Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
Figure 17-2: A sample JSP listing.
There are a number of JSP example pages that you can try out to test yourinstallation For example, click on the Execute link for the Date JSP page
You should see an output page similar to the one shown in Figure 17-3
Figure 17-3: Output of the /examples/jsp/
dates/date.jspfile
The JSP code for this JSP page is stored in /var/tomcat/webapps/examples/
jsp/dates/date.jsp, which is shown in Listing 17-3
Trang 39Listing 17-3: date.jsp
<html>
Copyright (c) 1999 The Apache Software Foundation All rights reserved.
<li> Day of month: is <jsp:getProperty name=”clock” property=”dayOfMonth”/>
<li> Year: is <jsp:getProperty name=”clock” property=”year”/>
<li> Month: is <jsp:getProperty name=”clock” property=”month”/>
<li> Time: is <jsp:getProperty name=”clock” property=”time”/>
<li> Date: is <jsp:getProperty name=”clock” property=”date”/>
<li> Day: is <jsp:getProperty name=”clock” property=”day”/>
<li> Day Of Year: is <jsp:getProperty name=”clock” property=”dayOfYear”/>
<li> Week Of Year: is <jsp:getProperty name=”clock” property=”weekOfYear”/>
<li> era: is <jsp:getProperty name=”clock” property=”era”/>
<li> DST Offset: is <jsp:getProperty name=”clock” property=”DSTOffset”/>
<li> Zone Offset: is <jsp:getProperty name=”clock” property=”zoneOffset”/>
</ul>
</font>
</body>
</html>
You can see that the JSP code is embedded in the HTML using the
<jsp:getProperty name=”name” property=”property_name””/>tags
If you return to the top page and click on the Servlet Examples link you will see apage as shown in Figure 17-4
Click on the Execute link for the Hello World servlet and you should see an outputpage as shown in Figure 17-5
Return to the previous page using the Web browser’s back button and click onthe Source link for Hello World to view the simplified source code for this servlet.The source code is shown in Figure 17-6
Trang 40489Chapter 17 ✦ Running Java Servlets and JSP Pages with Tomcat
Figure 17-4: Example servlet listings.
Figure 17-5: Output of /examples/servlet/HelloWorldExample
As you can see, this is a fairly simple servlet — it simply prints out a bunch of HTMLtags to create the output
Running your own servlets or JSP
This section teaches you to configure your own servlets to run via mod_jk Say thatyour servlet is called myapp Here is what you need to do to get it working withApache and Tomcat:
1 Create the following configuration in /var/tomcat/conf/server.xml: