{"id":1488,"date":"2012-09-25T15:33:03","date_gmt":"2012-09-25T07:33:03","guid":{"rendered":"http:\/\/rmohan.com\/?p=1488"},"modified":"2012-09-25T15:53:58","modified_gmt":"2012-09-25T07:53:58","slug":"apache-tomcat-7","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=1488","title":{"rendered":"Apache Tomcat 7"},"content":{"rendered":"<h5>TABLE OF CONTENTS <a id=\"show-toc\" href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#show-toc\">(HIDE)<\/a><\/h5>\n<p><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-1.\">1.\u00a0\u00a0Introduction<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-1.1\">1.1\u00a0\u00a0Web Application (Webapp)<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-1.2\">1.2\u00a0\u00a0Hypertext Transfer Protocol (HTTP)<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-1.3\">1.3\u00a0\u00a0Apache Tomcat HTTP Server<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.\">2.\u00a0\u00a0How to Install Tomcat 7 and Get Started with Java Servlet Programming<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.1\">2.1\u00a0\u00a0STEP 0: Read the Tomcat Documentation<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.2\">2.2\u00a0\u00a0STEP 1: Download and Install Tomcat<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.3\">2.3\u00a0\u00a0STEP 2: Create an Environment Variable JAVA_HOME<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.4\">2.4\u00a0\u00a0STEP 3: Configure Tomcat Server<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.5\">2.5\u00a0\u00a0STEP 4: Start Tomcat Server<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.6\">2.6\u00a0\u00a0STEP 5: Develop and Deploy a WebApp<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.7\">2.7\u00a0\u00a0STEP 6: Write a &#8220;Hello-world&#8221; Java Servlet<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.8\">2.8\u00a0\u00a0STEP 7: Write a Database Servlet<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-2.9\">2.9\u00a0\u00a0(Advanced) Deploying Servlet using @WebServlet (Servlet 3.0 on Tomcat 7)<\/a><br \/><a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#zz-3.\">3.\u00a0\u00a0How to Debug?<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>This tutorial can be completed in a 3-hour session, with guidance from instructor.<\/p>\n<p>This installation and configuration guide is applicable to Tomcat 7, and possibly the earlier versions.<\/p>\n<p>(EE3072 Students) This guide is applicable to &#8220;IM3072&#8221;, but NOT applicable to &#8220;EE3072&#8221;. For EE3072, please read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat6_HowTo.html\">Tomcat 6 &#8211; How to Install and Configure<\/a>&#8220;.<\/p>\n<h3>1.\u00a0\u00a0Introduction<\/h3>\n<h4>1.1\u00a0\u00a0Web Application (Webapp)<\/h4>\n<p>A <em>web application<\/em> (or webapp), unlike standalone application, runs over the Internet. Examples of web applications are google, amazon, ebay, facebook and twitter. A webapp is typically a <em>3-tier<\/em> (or <em>multi-tier<\/em>) <em>client-server application<\/em>, typically involving a <em>database<\/em>.<\/p>\n<p>Most of the webapps run on the HTTP application protocol, with browser as the client to access an HTTP server.<\/p>\n<p>A web database application requires five components, as illustrated below:<\/p>\n<ol>\n<li>HTTP Server: E.g., Apache HTTP Server, Apache Tomcat HTTP Server, Microsoft IIS, and etc.<\/li>\n<li>HTTP Client (or Web Browser): E.g., MSIE, FireFox, Chrome, and etc.<\/li>\n<li>Database: E.g., MySQL, Oracle, DB2, Infomix, MS SQL Server, MS Access, and etc.<\/li>\n<li>Client-Side Programs: could be written in HTML Form, JavaScript, VBScript, Flash, and etc.<\/li>\n<li>Server-Side Programs: could be written in Java Servlet\/JSP, ASP, PHP, and etc.<\/li>\n<\/ol>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/HTTP_ClientServerSystem.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1489\" title=\"HTTP_ClientServerSystem\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/HTTP_ClientServerSystem.png\" alt=\"\" width=\"844\" height=\"516\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/HTTP_ClientServerSystem.png 844w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/HTTP_ClientServerSystem-300x183.png 300w\" sizes=\"(max-width: 844px) 100vw, 844px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>A user, via a web browser, issue a URL to an HTTP server to start a webapp. The webapp first downloads a client-side program (such as an HTML form) into the browser. The user fills up the query criteria in the form. The client-side program sends the query parameters to a server-side program, which queries the database and returns the query result to the client. The client-side program displays the result on the browser.<\/p>\n<h4>1.2\u00a0\u00a0Hypertext Transfer Protocol (HTTP)<\/h4>\n<p>HTTP is an <em>asynchronous request-response application-layer protocol<\/em>. A client sends a request message to the server. The server returns a response message to the client. The syntax of the message is defined in the HTTP specification.<\/p>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/HTTP_RequestResponseMessages.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1490\" title=\"HTTP_RequestResponseMessages\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/HTTP_RequestResponseMessages.png\" alt=\"\" width=\"915\" height=\"567\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/HTTP_RequestResponseMessages.png 915w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/HTTP_RequestResponseMessages-300x185.png 300w\" sizes=\"(max-width: 915px) 100vw, 915px\" \/><\/a><\/p>\n<h4>.3\u00a0\u00a0Apache Tomcat HTTP Server<\/h4>\n<p><em>Apache Tomcat<\/em> is a Java-capable HTTP server, which could execute special Java programs known as Java Servlet and Java Server Pages (JSP). It is the official <em>Reference Implementation<\/em> (<em>RI<\/em>) for Java Servlets and JavaServer Pages (JSP) technologies. Tomcat is an <em>open-source<\/em> project, under the &#8220;Apache Software Foundation&#8221; (which also provides the famous open-source industrial-strength Apache HTTP Server). The mother site for Tomcat is <a href=\"http:\/\/tomcat.apache.org\/\">http:\/\/tomcat.apache.org<\/a>. Alternatively, you can find tomcat via the Apache mother site @ <a href=\"http:\/\/www.apache.org\/\">http:\/\/www.apache.org<\/a>.<\/p>\n<h3 id=\"TomcatInstall\">2.\u00a0\u00a0How to Install Tomcat 7 and Get Started with Java Servlet Programming<\/h3>\n<h4>2.1\u00a0\u00a0STEP 0: Read the Tomcat Documentation<\/h4>\n<p>Tomcat&#8217;s documentation is available at Tomcat mother site @ <a href=\"http:\/\/tomcat.apache.org\/\">http:\/\/tomcat.apache.org<\/a>. Select &#8220;Documentation&#8221; ? &#8220;Tomcat 7.0&#8221;.<\/p>\n<h4>2.2\u00a0\u00a0STEP 1: Download and Install Tomcat<\/h4>\n<ol>\n<li>From <a href=\"http:\/\/tomcat.apache.org\/\">http:\/\/tomcat.apache.org<\/a> ? Select &#8220;Downloads&#8221; ? &#8220;Tomcat 7.0&#8221; ? &#8220;7.0.xx&#8221; (where xx is the latest upgrade number) ? &#8220;Binary Distributions&#8221; ? &#8220;Core&#8221; ? &#8220;zip&#8221; ? &#8220;<code>apache-tomcat-7.0.xx.zip<\/code>&#8220;.<\/li>\n<li>UNZIP into a directory of your choice. DO NOT unzip onto the Desktop (because its path is hard to locate). I suggest using &#8220;<code>d:\\myproject<\/code>&#8220;. Tomcat will be unzipped into directory &#8220;<code>d:\\myproject\\apache-tomcat-7.0.xx<\/code>&#8220;. For ease of use, we shall shorten and rename this directory to &#8220;<code>d:\\myproject\\tomcat<\/code>&#8220;. <strong>Take note of Your Tomcat Installed Directory<\/strong>. Hereafter, I shall refer to the Tomcat installed directory as <code>&lt;TOMCAT_HOME&gt;<\/code>.<\/li>\n<\/ol>\n<p>I recommend &#8220;zip&#8221; version, as you could simply delete the entire directory when Tomcat is no longer needed (without running any un-installer). You are free to move or rename the Tomcat&#8217;s installed directory. You can install (unzip) multiple copies of Tomcat in the same machine.<\/p>\n<div>\n<p>(For Mac Users) Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/MacUsers_HowTo.html#mac_tomcat\">How to Install Tomcat 7 on Mac<\/a>&#8221; Step 1.<\/p>\n<\/div>\n<h4>2.3\u00a0\u00a0STEP 2: Create an Environment Variable JAVA_HOME<\/h4>\n<p>You need to create an <em>environment variable<\/em> called &#8220;<code>JAVA_HOME<\/code>&#8221; and set it to your JDK installed directory.<\/p>\n<ol>\n<li>First, take note of your JDK installed directory (the default is &#8220;<code>c:\\program files\\java\\jdk1.7.0<\/code>_xx&#8221;).<\/li>\n<li>Start a CMD shell, and issue the command &#8220;<code>SET JAVA_HOME<\/code>&#8221; to check if variable <code>JAVA_HOME<\/code>is set:\n<pre>prompt&gt; <strong>set JAVA_HOME<\/strong>\r\nEnvironment variable JAVA_HOME not defined<\/pre>\n<p>If <code>JAVA_HOME<\/code> is set (by other applications), check if it is set to your JDK installed directory.<\/p>\n<\/li>\n<li>To set\/change an environment variable in Windows 2000\/XP\/Vista\/7: Click &#8220;Start&#8221; button ? &#8220;Control Panel&#8221; ? &#8220;System&#8221; ? (Vista\/7) &#8220;Advanced system settings&#8221; ? Switch to &#8220;Advanced&#8221; tab ? &#8220;Environment Variables&#8221; ? &#8220;System Variables&#8221; (or &#8220;User Variables&#8221; for the current user only) ? &#8220;New&#8221; (or &#8220;Edit&#8221; for modification) ? In &#8220;Variable Name&#8221; field, enter &#8220;<code>JAVA_HOME<\/code>&#8221; ? In &#8220;Variable Value&#8221; field, enter your JDK installed directory (e.g., &#8220;<code>c:\\program file\\java\\jdk1.7.0<\/code>&#8220;) &#8211; I suggest that you copy and paste the directory name to avoid typo error!<\/li>\n<li>To verify, <strong>RE-START<\/strong>a CMD shell and issue:\n<pre>prompt&gt; <strong>set JAVA_HOME<\/strong>\r\nJAVA_HOME=c:\\program file\\java\\jdk1.7.0   &lt;== CHECK! YOUR JDK installed directory<\/pre>\n<\/li>\n<\/ol>\n<div>\n<p>(For Mac Users) Take note of your JDK installed directory (most likely under <code>\/usr\/local<\/code>). Start a Terminal and run:<\/p>\n<pre>$ echo $JAVA_HOME                       \/\/ Check if JAVA_HOME is already set\r\n\r\n\/\/ If JAVA_HOME is not set, then\r\n$ java_home=<em>your_jdk_install_directory<\/em>  \/\/ Set environment variable java_home\r\n$ export java_home                      \/\/ Make this variable available to all applications<\/pre>\n<p>To make permanent changes, store the above command in &#8220;<code>.bash_profile<\/code>&#8221; in your home directory (denoted as <code>'~'<\/code>), and run &#8220;<code>source $HOME\/.bash_profile<\/code>&#8221; to refresh.<\/p>\n<\/div>\n<h4>2.4\u00a0\u00a0STEP 3: Configure Tomcat Server<\/h4>\n<p>(Note) Programmers need to view the <em>file extension<\/em> (such as <code>.txt<\/code>, <code>.ini<\/code>). To display the file extension in Windows, run &#8220;Control Panel&#8221; ? &#8220;Folder Options&#8221; ? Select tab &#8220;View&#8221; ? Uncheck &#8220;Hide extensions for known file types&#8221;.<\/p>\n<p>The Tomcat configuration files are located in the &#8220;<code>conf<\/code>&#8221; sub-directory of your Tomcat installed directory (e.g. &#8220;<code>d:\\myproject\\tomcat\\conf<\/code>&#8220;). There are 3 configuration files:<\/p>\n<ol>\n<li><code>server.xml<\/code><\/li>\n<li><code>web.xml<\/code><\/li>\n<li><code>context.xml<\/code><\/li>\n<\/ol>\n<p>Make a backup of the configuration files before you proceed.<\/p>\n<h5>Step 3(a) &#8220;server.xml&#8221; &#8211; <strong>Set the TCP Port Number<\/strong><\/h5>\n<p>Use a text editor (e.g., NotePad++, TextPad or NotePad) to open the configuration file &#8220;<code>server.xml<\/code>&#8220;, under the &#8220;<code>conf<\/code>&#8221; sub-directory of Tomcat installed directory (e.g. &#8220;<code>d:\\myproject\\tomcat\\conf<\/code>&#8220;).<\/p>\n<p>The default TCP port number configured in Tomcat is 8080, you may choose any number between 1024 and 65535, which is not used by an existing application. We shall use port 9999 in this article. (For production server, you should use port 80, which is pre-assigned to HTTP server as the default port number.)<\/p>\n<pre>&lt;!-- Define a <strong>non-SSL HTTP\/1.1 Connector<\/strong> on port 8080 --&gt;\r\n&lt;Connector <strong>port=\"9999\"<\/strong> protocol=\"<strong>HTTP\/1.1<\/strong>\" connectionTimeout=\"20000\" redirectPort=\"8443\" \/&gt;<\/pre>\n<h5>Step 3(b) &#8220;web.xml&#8221; &#8211; <strong>Enabling Directory Listing<\/strong><\/h5>\n<p>Again, use a text editor to open the configuration file &#8220;<code>web.xml<\/code>&#8220;, under the &#8220;<code>conf<\/code>&#8221; sub-directory of Tomcat installed directory.<\/p>\n<p>We shall enable directory listing by changing &#8220;<code>listings<\/code>&#8221; from &#8220;<code>false<\/code>&#8221; to &#8220;<code>true<\/code>&#8221; for the &#8220;<code>default<\/code>&#8221; servlet, as shown in red.<\/p>\n<pre>&lt;!-- The default servlet for all web applications, that serves static     --&gt;\r\n&lt;!-- resources.  It processes all requests that are not mapped to other   --&gt;\r\n&lt;!-- servlets with servlet mappings.                                      --&gt;\r\n&lt;servlet&gt;\r\n  &lt;servlet-name&gt;<strong>default<\/strong>&lt;\/servlet-name&gt;\r\n  &lt;servlet-class&gt;org.apache.catalina.servlets.DefaultServlet&lt;\/servlet-class&gt;\r\n  &lt;init-param&gt;\r\n    &lt;param-name&gt;debug&lt;\/param-name&gt;\r\n    &lt;param-value&gt;0&lt;\/param-value&gt;\r\n  &lt;\/init-param&gt;\r\n  &lt;init-param&gt;\r\n    &lt;param-name&gt;<strong>listings<\/strong>&lt;\/param-name&gt;\r\n    &lt;param-value&gt;<strong>true<\/strong>&lt;\/param-value&gt;\r\n  &lt;\/init-param&gt;\r\n  &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;\r\n&lt;\/servlet&gt;<\/pre>\n<h5>Step 3(c) &#8220;context.xml&#8221; &#8211; <strong>Enabling Automatic Reload<\/strong><\/h5>\n<p>Again, use a text editor to open the configuration file &#8220;<code>context.xml<\/code>&#8220;, under the &#8220;<code>conf<\/code>&#8221; sub-directory of Tomcat installed directory.<\/p>\n<p>We shall add the attribute <code>reloadable=\"true\"<\/code> to the <code>&lt;Context&gt;<\/code> element to enable automatic reload after code changes, as shown in red.<\/p>\n<pre>&lt;Context <strong>reloadable=\"true\"<\/strong>&gt;\r\n   ......\r\n&lt;\/Context&gt;<\/pre>\n<h4>2.5\u00a0\u00a0STEP 4: Start Tomcat Server<\/h4>\n<p>The Tomcat&#8217;s executable programs are kept in the &#8220;<code>bin<\/code>&#8221; sub-directory of the Tomcat installed directory (e.g., &#8220;<code>d:\\myproject\\tomcat\\bin<\/code>&#8220;).<\/p>\n<h5>Step 4(a) Start Server<\/h5>\n<p>Launch a CMD shell. Set the current directory to &#8220;<code>&lt;TOMCAT_HOME<\/code>&gt;\\<code>bin<\/code>&#8220;, and run &#8220;<code>startup.bat<\/code>&#8221; as follows:<\/p>\n<pre>\/\/ Change the current directory to Tomcat's \"bin\"\r\n\/\/ Assume that Tomcat is installed in \"d:\\myproject\\tomcat\"\r\nprompt&gt; <strong>d:<\/strong>                     \/\/ Change the current drive\r\nD:\\...&gt; <strong>cd \\<\/strong>                   \/\/ Change Directory to ROOT directory\r\nD:\\&gt; <strong>cd \\myproject\\tomcat\\bin<\/strong>  \/\/ Change Directory to YOUR Tomcat's \"bin\" directory\r\n \r\n\/\/ Start Tomcat Server\r\nD:\\myproject\\tomcat\\bin&gt; <strong>startup<\/strong><\/pre>\n<p>A new Tomcat console window appears. Study the messages on the console. Look out for the Tomcat&#8217;s port number (double check that Tomcat is running on port 9999). Future error messages will be send to this console. <code>System.out.println()<\/code> issued by your Java servlets will also be sent to this console.<\/p>\n<pre>......\r\nINFO: Initializing Coyote <strong>HTTP\/1.1 on http-9999<\/strong>\r\n......\r\nINFO: Starting Coyote <strong>HTTP\/1.1 on http-9999<\/strong>\r\n......\r\nINFO: Server startup in 699 ms<\/pre>\n<div>\n<p>(For Mac Users) Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/MacUsers_HowTo.html#mac_tomcat\">How to Install Tomcat 7 on Mac<\/a>&#8221; Step 2.<\/p>\n<\/div>\n<h5>Step 4(b) Start a Client to Access the Server<\/h5>\n<p>Start a browser (as a HTTP client), and issue URL &#8220;<code>http:\/\/localhost:9999<\/code>&#8221; to access the Tomcat server&#8217;s welcome page. The hostname &#8220;<code>localhost<\/code>&#8221; (with IP address of <code>127.0.0.1<\/code>) is meant for local loop-back testing. For users on the other machines over the net, they have to use the server&#8217;s IP address or DNS domain name or hostname in the format of &#8220;<code>http:\/\/<em>serverHostnameOrIPAddress<\/em>:9999<\/code>&#8220;.<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatHomePage.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter  wp-image-1491\" title=\"TomcatHomePage\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatHomePage.png\" alt=\"\" width=\"796\" height=\"90\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatHomePage.png 1008w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatHomePage-300x33.png 300w\" sizes=\"(max-width: 796px) 100vw, 796px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h5>Step 4(c) Shutdown Server<\/h5>\n<p>You can shutdown the server by running &#8220;<code>&lt;TOMCAT_HOME&gt;\\bin\\<strong>shutdown.bat<\/strong><\/code>&#8220;. If Tomcat does not respond to the shutdown command, you could terminate Tomcat by pushing <em>control-c<\/em> (or <em>control-break<\/em>) on the Tomcat&#8217;s console. DO NOT kill the cat by pushing the &#8220;close&#8221; button.<\/p>\n<h5>(Skip Unless &#8230;) Cannot Start Tomcat<\/h5>\n<ul>\n<li><strong>Check the Error Messages on Tomcat&#8217;s Console<\/strong>. Most of the error messages have tens of lines. You need to scroll up slowly from the last message to look for the <em>first-line<\/em> of the error messages.<\/li>\n<li>Check the Tomcat&#8217;s log files, located at <code>\"&lt;TOMCAT_HOME&gt;\\logs<\/code>&#8220;. &#8220;<code>catalina.<em>yyyy-mm-dd<\/em>.log<\/code>&#8221; shows the Tomcat&#8217;s startup messages. Also check the &#8220;<code>localhost.<em>yyyy-mm-dd<\/em>.log<\/code>&#8220;.<\/li>\n<\/ul>\n<p>Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/ErrorMessages.html#TomcatErrorsStartup\">Common Errors in Starting Tomcat after Installation<\/a>&#8220;.<\/p>\n<h4>2.6\u00a0\u00a0STEP 5: Develop and Deploy a WebApp<\/h4>\n<h5>Step 5(a) Create the Directory Structure for your WebApp<\/h5>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatWebappHello.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1492\" title=\"TomcatWebappHello\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatWebappHello.png\" alt=\"\" width=\"169\" height=\"194\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>First of all, choose a <em>name<\/em> for your webapp. Let us call it &#8220;<code>hello<\/code>&#8220;. Navigate to Tomcat&#8217;s &#8220;<code>webapps<\/code>&#8221; sub-directory, and create the following directory structure for you webapp &#8220;<code>hello<\/code>&#8220;, as illustrated:<\/p>\n<ol>\n<li>Under Tomcat&#8217;s &#8220;<code>webapps<\/code>&#8220;, create your web application <em>root<\/em> directory &#8220;<code>hello<\/code>&#8221; (i.e., &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello<\/code>&#8220;).<\/li>\n<li>Under &#8220;<code>hello<\/code>&#8220;, create a sub-directory &#8220;<code>WEB-INF<\/code>&#8221; (case sensitive, a &#8220;dash&#8221; not an underscore) (i.e., &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF<\/code>&#8220;).<\/li>\n<li>Under &#8220;<code>WEB-INF<\/code>&#8220;, create a sub-directory &#8220;<code>classes<\/code>&#8221; (case sensitive, plural) (i.e., &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF\\classes<\/code>&#8220;).<\/li>\n<\/ol>\n<p>You need to keep your web resources (e.g., HTMLs, CSSs, images, scripts, servlets, JSPs) in the proper directories:<\/p>\n<ul>\n<li>&#8220;<code>hello<\/code>&#8220;: The is called the <em>context root<\/em> (or <em>document base directory<\/em>) of your web application. You should keep all your HTML files and resources visible to the web users (e.g., CSSs, images, scripts, JSPs) under this <em>context root<\/em>.<\/li>\n<li>&#8220;<code>hello\\WEB-INF<\/code>&#8220;: This directory, although under the context root, is <em>not visible<\/em> to the web users. This is where you keep your application&#8217;s configuration files &#8220;<code>web.xml<\/code>&#8220;.<\/li>\n<li>&#8220;<code>hello\\WEB-INF\\classes<\/code>&#8220;: This is where you keep all the Java classes such as servlet class-files.<\/li>\n<\/ul>\n<p>You should RE-START your Tomcat server. Check the Tomcat&#8217;s console to confirm that &#8220;<code>hello<\/code>&#8221; application has been properly depolyed:<\/p>\n<pre>......\r\nINFO: Deploying web application directory ...\\<strong>hello<\/strong>\r\n......<\/pre>\n<p>You can issue the following URL to access the web application &#8220;<code>hello<\/code>&#8220;:<\/p>\n<pre>http:\/\/localhost:9999<strong>\/hello<\/strong><\/pre>\n<p>You should see the directory listing of the directory &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello<\/code>&#8220;, which shall be empty.<\/p>\n<h5>Step 5(b) Write a Welcome Page<\/h5>\n<p>Create the following HTML page and save as &#8220;<code>HelloHome.html<\/code>&#8221; in your application&#8217;s root directory &#8220;<code>hello<\/code>&#8220;.<\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6<\/pre>\n<\/td>\n<td>\n<pre>&lt;html&gt;\r\n  &lt;head&gt;&lt;title&gt;My Home Page&lt;\/title&gt;&lt;\/head&gt;\r\n  &lt;body&gt;\r\n    &lt;h1&gt;My Name is so and so. This is my HOME.&lt;\/h1&gt;\r\n  &lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You can browse this page by issuing this URL:<\/p>\n<p>You can browse this page by issuing this URL:<\/p>\n<pre>http:\/\/localhost:9999\/hello\/<strong>HelloHome.html<\/strong><\/pre>\n<p><img decoding=\"async\" src=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/images\/TomcatWebappHelloHome.png\" alt=\"\" \/><\/p>\n<p>Alternatively, you can issue an URL to your web application root &#8220;<code>hello<\/code>&#8220;:<\/p>\n<pre>http:\/\/localhost:9999\/hello<\/pre>\n<p>T<\/p>\n<p>Now, the server will redirect the directory request to &#8220;<code>index.html<\/code>&#8220;, if the root directory contains an &#8220;<code>index.html<\/code>&#8220;, instead of serving the directory listing.<\/p>\n<p>You can check out the home page of your peers by issuing (or access your own server from another machine):<\/p>\n<pre>http:\/\/<em>YourPeerHostnameOrIPAddress<\/em>:9999\/hello\r\nhttp:\/\/<em>YourPeerHostnameOrIPAddress<\/em>:9999\/hello\/HelloHome.html\r\nhttp:\/\/<em>YourPeerHostnameOrIPAddress<\/em>:9999\/hello\/index.html<\/pre>\n<p>with a valid &#8220;<code><em>YourPeerHostnameOrIPAddress<\/em><\/code>&#8220;, provided that your peer has started his\/her web server. You can use command such as &#8220;<code>ipconfig<\/code>&#8220;, &#8220;<code>winipcfg<\/code>&#8220;, &#8220;<code>ping<\/code>&#8221; to find your IP address.<\/p>\n<p>&nbsp;<\/p>\n<p>(Skip Unless&#8230;) The likely errors are &#8220;Unable to Connect&#8221;, &#8220;Internet Explorer cannot display the web page&#8221;, and &#8220;404 File Not Found&#8221;. Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#TomcatDebug\">How to Debug<\/a>&#8221; section.<\/p>\n<h4>2.7\u00a0\u00a0STEP 6: Write a &#8220;Hello-world&#8221; Java Servlet<\/h4>\n<p>A <em>servlet<\/em> is Java program that runs inside a Java-capable HTTP Server, such as Apache Tomcat. A web user invokes a servlet by issuing an appropriate URL from a web browser (or HTTP client).<\/p>\n<p>Before you proceed, I shall assume that you are familiar with Java Programming and have installed the followings:<\/p>\n<ol>\n<li>JDK (Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/JDK_HowTo.html\">How to install JDK and Get Started<\/a>&#8220;).<\/li>\n<li>A programming text editor, such as TextPad or Notepad++ (Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/ProgrammingTextEditors_HowTo.html\">Programming Text Editor<\/a>&#8220;); or a Java IDE such as Eclipse or NetBeans (Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/EclipseJava_HowTo.html\">How to Install Eclipse<\/a>&#8221; or &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/NetBeans_HowTo.html\">How to Install NetBeans<\/a>&#8220;).<\/li>\n<\/ol>\n<h5 id=\"InstallServletAPI\">Step 6(a) Install Servlet API Library<\/h5>\n<p>Before we can write our first servlet, we need to install the Servlet API. Servlet API is not part of JDK (but belongs to Java EE). Tomcat also includes a copy of Servlets API.<\/p>\n<p>COPY the Tomcat&#8217;s Servlet API JAR-file located at &#8220;<code>&lt;TOMCAT_HOME&gt;\\<strong>lib\\servlet-api.jar<\/strong><\/code>&#8220;, (e.g., &#8220;<code>d:\\myproject\\tomcat\\<strong>lib\\servlet-api.jar<\/strong><\/code>&#8220;) into JDK&#8217;s <em>extension<\/em> directory at &#8220;<code>&lt;JAVA_HOME&gt;\\<strong>jre\\lib\\ext<\/strong><\/code>&#8220;, (e.g., &#8220;<code>c:\\program files\\java\\jdk1.7.0\\<strong>jre\\lib\\ext<\/strong><\/code>&#8220;).<\/p>\n<div>\n<p>(For Advanced Users Only) Alternatively, you could include the Servlet API JAR-file in the <code>CLASSPATH<\/code>. Open &#8220;Control Panel&#8221; ? System ? (Vista\/7 only) Advanced system settings ? Switch to &#8220;Advanced&#8221; tab ? Environment variables ? Choose &#8220;System Variables&#8221; (for all users in this system) or &#8220;User Variables&#8221; (for this login user only) ? Choose &#8220;New&#8221; or &#8220;Edit&#8221;? In &#8220;Variable Name&#8221;, enter &#8220;classpath&#8221; ? In &#8220;Variable Value&#8221;, enter &#8220;<code>.;<em>path-to<\/em>\\servlet-api.jar<\/code>&#8220;, where &#8220;<code><em>path-to<\/em><\/code>&#8221; includes the drive letter and path of the Servlet API jar-file &#8220;<code>servlet-api.jar<\/code>&#8220;. You can also compile your program using &#8220;<code>javac -cp .;<em>path-to<\/em>\\servlet-api.jar ServletName<\/code>&#8220;.<\/p>\n<\/div>\n<h5>Step 6(b) Write a &#8220;Hello-world&#8221; Java Servlet<\/h5>\n<p>A Java servlet is a Java program that runs inside a HTTP server. A web user invokes a servlet by issuing a URL from a browser (or HTTP client).<\/p>\n<p>In this example, we are going to write a Java servlet called <code>HelloServlet<\/code>, which says &#8220;Hello, world!&#8221;. We will then write a configuration such that web users can invoke this servlet by issuing URL <code>http:\/\/<em>hostname<\/em>:<em>port<\/em>\/hello\/sayhello<\/code> from the browser, as illustrated:<\/p>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatWebappHelloServlet.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1495\" title=\"TomcatWebappHelloServlet\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatWebappHelloServlet.png\" alt=\"\" width=\"819\" height=\"341\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatWebappHelloServlet.png 819w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatWebappHelloServlet-300x124.png 300w\" sizes=\"(max-width: 819px) 100vw, 819px\" \/><\/a><\/p>\n<p>Write the following source codes called &#8220;<code>HelloServlet.java<\/code>&#8221; and save it under your application &#8220;<code>classes<\/code>&#8221; directory (i.e., &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello\\<strong>WEB-INF\\classes<\/strong>\\HelloServlet.java<\/code>&#8220;). Compile the source into &#8220;<code>HelloServlet.class<\/code>&#8220;. This servlet says &#8220;Hello&#8221;, echos some request information, and prints a random number upon each request.<\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34<\/pre>\n<\/td>\n<td>\n<pre>\/\/ To save as \"&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF\\classes\\HelloServlet.java\"\r\nimport java.io.*;\r\nimport javax.servlet.*;\r\nimport javax.servlet.http.*;\r\n \r\npublic class <strong>HelloServlet<\/strong> extends HttpServlet {\r\n   @Override\r\n   public void <strong>doGet<\/strong>(HttpServletRequest <strong>request<\/strong>, HttpServletResponse <strong>response<\/strong>)\r\n         throws IOException, ServletException {\r\n \r\n      \/\/ Set the response MIME type of the response message\r\n      <strong>response.setContentType(\"text\/html\");<\/strong>\r\n      \/\/ Allocate a output writer to write the response message into the network socket\r\n      <strong>PrintWriter out = response.getWriter();<\/strong>\r\n \r\n      \/\/ Write the response message, in an HTML page\r\n      try {\r\n         out.println(\"&lt;html&gt;\");\r\n         out.println(\"&lt;head&gt;&lt;title&gt;Hello, World&lt;\/title&gt;&lt;\/head&gt;\");\r\n         out.println(\"&lt;body&gt;\");\r\n         out.println(\"&lt;h1&gt;Hello, world!&lt;\/h1&gt;\");  \/\/ says Hello\r\n         \/\/ Echo client's request information\r\n         out.println(\"&lt;p&gt;Request URI: \" + <strong>request.getRequestURI()<\/strong> + \"&lt;\/p&gt;\");\r\n         out.println(\"&lt;p&gt;Protocol: \" + <strong>request.getProtocol()<\/strong> + \"&lt;\/p&gt;\");\r\n         out.println(\"&lt;p&gt;PathInfo: \" + <strong>request.getPathInfo()<\/strong> + \"&lt;\/p&gt;\");\r\n         out.println(\"&lt;p&gt;Remote Address: \" + <strong>request.getRemoteAddr()<\/strong> + \"&lt;\/p&gt;\");\r\n         \/\/ Generate a random number upon each request\r\n         out.println(\"&lt;p&gt;A Random Number: &lt;strong&gt;\" + <strong>Math.random()<\/strong> + \"&lt;\/strong&gt;&lt;\/p&gt;\");\r\n         out.println(\"&lt;\/body&gt;&lt;\/html&gt;\");\r\n      } finally {\r\n         out.close();  \/\/ Always close the output writer\r\n      }\r\n   }\r\n}<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>(Skip Unless&#8230;) Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/ErrorMessages.html#ServletErrors\">Common Errors in Compiling Java Servlet<\/a>&#8220;.<\/p>\n<h5>Step 6(c) Configure Servlet&#8217;s Request URL in &#8220;<code>webapps\\hello\\WEB-INF\\web.xml<\/code>&#8220;<\/h5>\n<p>A web user invokes a servlet, which is kept in the web server, by issuing <em>a request URL<\/em> from the browser. We need to configure this request URL for our <code>HelloServlet<\/code>.<\/p>\n<p>Create the following configuration file called &#8220;<code><strong>web.xml<\/strong><\/code>&#8220;, and save it under &#8220;<strong><code>webapps\\hello\\WEB-INF<\/code><\/strong>&#8221; (i.e., &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF\\web.xml<\/code>&#8220;).<\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21<\/pre>\n<\/td>\n<td>\n<pre>&lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\"?&gt;\r\n&lt;web-app version=\"3.0\"\r\n  xmlns=\"http:\/\/java.sun.com\/xml\/ns\/javaee\"\r\n  xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n  xsi:schemaLocation=\"http:\/\/java.sun.com\/xml\/ns\/javaee http:\/\/java.sun.com\/xml\/ns\/javaee\/web-app_3_0.xsd\"&gt;\r\n \r\n   <strong>&lt;!-- To save as \"hello\\WEB-INF\\web.xml\" --&gt;<\/strong>\r\n \r\n   &lt;servlet&gt;\r\n      &lt;servlet-name&gt;<strong>HelloWorld<\/strong>&lt;\/servlet-name&gt;\r\n      &lt;servlet-class&gt;<strong>HelloServlet<\/strong>&lt;\/servlet-class&gt;\r\n   &lt;\/servlet&gt;\r\n \r\n   <strong>&lt;!-- Note: All &lt;servlet&gt; elements MUST be grouped together and placed IN FRONT of the &lt;servlet-mapping&gt; elements --&gt;<\/strong>\r\n \r\n   &lt;servlet-mapping&gt;\r\n      &lt;servlet-name&gt;<strong>HelloWorld<\/strong>&lt;\/servlet-name&gt;\r\n      &lt;url-pattern&gt;<strong>\/sayhello<\/strong>&lt;\/url-pattern&gt;\r\n   &lt;\/servlet-mapping&gt;\r\n&lt;\/web-app&gt;<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In the above configuration, a servlet having a class file &#8220;<code>HelloServlet.class<\/code>&#8221; is mapped to request URL &#8220;<code>\/sayhello<\/code>&#8221; (via an <em>arbitrary<\/em> <code>servlet-name<\/code> &#8220;<code>HelloWorld<\/code>&#8220;), under this web application &#8220;<code>hello<\/code>&#8220;. In other words, the complete request URL for this servlet is &#8220;<code>http:\/\/<em>hostname<\/em>:<em>port<\/em><strong>\/hello\/sayhello<\/strong><\/code>&#8220;.<\/p>\n<p>This configuration file, saved under your web application &#8220;<code>hello<\/code>&#8220;, is applicable only to this particular web application &#8220;<code>hello<\/code>&#8220;.<\/p>\n<p>Restart your Tomcat server.<\/p>\n<p>IMPORTANT: For EACH servlet, you need to write a pair of <code>&lt;servlet&gt;<\/code> and <code>&lt;servlet-mapping&gt;<\/code> elements with a common <code>&lt;servlet-name&gt;<\/code>. Take note that all the <code>&lt;servlet&gt;<\/code> elements MUST be grouped together and placed IN FRONT of the <code>&lt;servlet-mapping&gt;<\/code> elements.<\/p>\n<h5>Step 6(d) Invoke the Servlet<\/h5>\n<p>To run this servlet, start a browser, and issue the request URL configured earlier:<\/p>\n<pre>http:\/\/localhost:9999\/<strong>hello\/sayhello<\/strong><\/pre>\n<p>You shall see the output of the servlet displayed in your web browser.<\/p>\n<p>Refresh the browser, you shall see a new random number upon each refresh. In other word, the <code>doGet()<\/code> method of the servlet runs once per request.<\/p>\n<p>Try &#8220;View Source&#8221; to look at the output received by the web users. Take note that the web users receive only the output of the servlet (generated via the <code>out.println()<\/code> statements). They have no access to the servlet programs (which may contain confidential information).<\/p>\n<pre>&lt;html&gt;\r\n&lt;head&gt;&lt;title&gt;Hello, World&lt;\/title&gt;&lt;\/head&gt;\r\n&lt;body&gt;\r\n&lt;h1&gt;Hello, world!&lt;\/h1&gt;\r\n&lt;p&gt;Request URI: \/hello\/sayhello&lt;\/p&gt;\r\n&lt;p&gt;Protocol: HTTP\/1.1&lt;\/p&gt;\r\n&lt;p&gt;PathInfo: null&lt;\/p&gt;\r\n&lt;p&gt;Remote Address: 127.0.0.1&lt;\/p&gt;\r\n&lt;p&gt;A Random Number: &lt;strong&gt;0.3523682325749493&lt;\/strong&gt;&lt;\/p&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>&nbsp;<\/p>\n<p>(Skip Unless&#8230;) The likely errors are &#8220;404 File Not Found&#8221; and &#8220;500 Internal Server Error&#8221;. Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#TomcatDebug\">How to debug<\/a>&#8221; Section.<\/p>\n<h4 id=\"DatabaseServlet\">2.8\u00a0\u00a0STEP 7: Write a Database Servlet<\/h4>\n<p>This section assumes that you are familiar with Java database programming and MySQL database server. Otherwise, read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/sql\/MySQL_HowTo.html\">How to Install MySQL and Get Started<\/a>&#8220;.<\/p>\n<h5>Step 7(a) Setup a Database on MySQL<\/h5>\n<p>Start your MySQL server. Take note of the server&#8217;s port number. I shall assume that the MySQL server is running on port <code>8888<\/code> (whereas the Tomcat is running on port <code>9999<\/code>).<\/p>\n<pre>D:\\myproject\\mysql\\bin&gt; <strong>mysqld --console<\/strong><\/pre>\n<p>Start a MySQL client. I shall assume that there is a user called &#8220;<code>myuser<\/code>&#8221; with password &#8220;<code>xxxx<\/code>&#8220;.<\/p>\n<pre>D:\\myproject\\mysql\\bin&gt; <strong>mysql -u <em>myuser<\/em> -p<\/strong><\/pre>\n<p>Run the following SQL statements to create a database called &#8220;<code>ebookshop<\/code>&#8220;, with a table called &#8220;<code>books<\/code>&#8221; with 5 columns: <code>id<\/code>, <code>title<\/code>, <code>author<\/code>, <code>price<\/code>, <code>qty<\/code>.<\/p>\n<pre>create database if not exists <strong>ebookshop<\/strong>;\r\n\r\nuse ebookshop;\r\n\r\ndrop table if exists books;\r\ncreate table <strong>books<\/strong> (\r\n   <strong>id<\/strong>     int,\r\n   <strong>title<\/strong>  varchar(50),\r\n   <strong>author<\/strong> varchar(50),\r\n   <strong>price<\/strong>  float,\r\n   <strong>qty<\/strong>    int,\r\n   primary key (id));\r\n\r\ninsert into books values (1001, 'Java for dummies', 'Tan Ah Teck', 11.11, 11);\r\ninsert into books values (1002, 'More Java for dummies', 'Tan Ah Teck', 22.22, 22);\r\ninsert into books values (1003, 'More Java for more dummies', 'Mohammad Ali', 33.33, 33);\r\ninsert into books values (1004, 'A Cup of Java', 'Kumar', 55.55, 55);\r\ninsert into books values (1005, 'A Teaspoon of Java', 'Kevin Jones', 66.66, 66);\r\n\r\nselect * from books;<\/pre>\n<h5>Step 7(b) Install MySQL JDBC Driver<\/h5>\n<p>You need to download MySQL JDBC driver if you have not done so. Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/sql\/MySQL_HowTo.html#MySQLJDBCDriver\">Installing the MySQL JDBC Driver<\/a>&#8220;.<\/p>\n<div>\n<p>(For Advanced User Only) You could also place the MySQL driver jar-file &#8220;<code>mysql-connector-java-5.1.xx-bin.jar<\/code>&#8221; in Tomcat&#8217;s &#8220;<code>lib<\/code>&#8221; directory.<\/p>\n<\/div>\n<h5>Step 7(c) Write a Client-side HTML Form<\/h5>\n<p>Let&#8217;s write an HTML script to create a <em>query form<\/em> with 3 checkboxes and a submit button, as illustrated below.\u00a0 Save the HTML file as \u201c<code>querybook.html<\/code>\u201d in your application root directory \u201c<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello<\/code>\u201d.<\/p>\n<p>\u00a0<a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/HtmlFormBookQuery.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1496\" title=\"HtmlFormBookQuery\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/HtmlFormBookQuery.png\" alt=\"\" width=\"452\" height=\"87\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/HtmlFormBookQuery.png 452w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/HtmlFormBookQuery-300x57.png 300w\" sizes=\"(max-width: 452px) 100vw, 452px\" \/><\/a><\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15<\/pre>\n<\/td>\n<td>\n<pre>&lt;html&gt;\r\n&lt;head&gt;\r\n  &lt;title&gt;Yet Another Bookshop&lt;\/title&gt;\r\n&lt;\/head&gt;\r\n&lt;body&gt;\r\n  &lt;h2&gt;Yet Another Bookshop&lt;\/h2&gt;\r\n  &lt;form method=\"get\" <strong>action=\"http:\/\/localhost:9999\/hello\/doquery\"<\/strong>&gt;\r\n    &lt;b&gt;Choose an author:&lt;\/b&gt;\r\n    &lt;input type=\"checkbox\" <strong>name=\"author\" value=\"Tan Ah Teck\"<\/strong>&gt;Ah Teck\r\n    &lt;input type=\"checkbox\" <strong>name=\"author\" value=\"Mohammad Ali\"<\/strong>&gt;Ali\r\n    &lt;input type=\"checkbox\" <strong>name=\"author\" value=\"Kumar\"<\/strong>&gt;Kumar\r\n    &lt;input type=\"submit\" value=\"Search\"&gt;\r\n  &lt;\/form&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You can browse the HTML page by issuing the following URL:<\/p>\n<pre>http:\/\/localhost:9999\/<strong>hello\/querybook.html<\/strong><\/pre>\n<p>Check a box (e.g., &#8220;Tan Ah Teck&#8221;) and click the &#8220;Search&#8221; button.\u00a0 An HTTP GET request will be issued to the URL specified in the <code>&lt;form&gt;<\/code>&#8216;s &#8220;<code>action<\/code>&#8221; attribute.\u00a0 Observe the URL of the HTTP GET request:<\/p>\n<pre>http:\/\/localhost:9999\/hello\/doquery<strong>?author=Tan+Ah+Teck<\/strong><\/pre>\n<p>The request consists of two part: a URL corresponding to the &#8220;<code>action<\/code>&#8221; attribute of the <code>&lt;form&gt;<\/code> tag, and the &#8220;name=value&#8221; pair extracted from the <code>&lt;input&gt;<\/code> tag, separated by a <code>'?'<\/code>. Take note that blanks are replaced by <code>'+'<\/code> (or <code>%20<\/code>), because blanks are not allowed in the URL.<\/p>\n<p>If you check two boxes (e.g., &#8220;Tan Ah Teck&#8221; and &#8220;Mohammad Ali&#8221;), you will get this URL, which has two &#8220;name=value&#8221; pairs separated by an <code>'&amp;'<\/code>.<\/p>\n<pre>http:\/\/localhost:9999\/hello\/doquery<strong>?author=Tan+Ah+Teck&amp;author=Mohammad+Ali<\/strong><\/pre>\n<p>You are expected to get an error &#8220;404 File Not Found&#8221;, as you have yet to write the server-side program.<\/p>\n<h5>Step 7(d) Write the Server-side Database Query Servlet<\/h5>\n<p>The next step is to write a Java servlet, which responses to the client\u2019s request by querying the database and returns the query results.<\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n61\r\n62\r\n63\r\n64<\/pre>\n<\/td>\n<td>\n<pre>\/\/ To save as \"&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF\\<strong>classes\\QueryServlet.java<\/strong>\".\r\nimport java.io.*;\r\nimport java.sql.*;\r\nimport javax.servlet.*;\r\nimport javax.servlet.http.*;\r\n \r\npublic class <strong>QueryServlet<\/strong> extends HttpServlet {  \/\/ JDK 6 and above only\r\n \r\n   \/\/ The doGet() runs once per HTTP GET request to this servlet.\r\n   @Override\r\n   public void doGet(HttpServletRequest request, HttpServletResponse response)\r\n               throws ServletException, IOException {\r\n      \/\/ Set the MIME type for the response message\r\n      response.setContentType(\"text\/html\");\r\n      \/\/ Get a output writer to write the response message into the network socket\r\n      PrintWriter out = response.getWriter();\r\n \r\n      Connection conn = null;\r\n      Statement stmt = null;\r\n      try {\r\n         \/\/ Step 1: Allocate a database Connection object\r\n         <strong>conn = DriverManager.getConnection( \"jdbc:mysql:\/\/localhost:8888\/ebookshop\", \"myuser\", \"xxxx\");<\/strong> \/\/ &lt;== Check!\r\n            \/\/ database-URL(hostname, port, default database), username, password\r\n \r\n         \/\/ Step 2: Allocate a Statement object within the Connection\r\n         <strong>stmt = conn.createStatement();<\/strong>\r\n \r\n         \/\/ Step 3: Execute a SQL SELECT query\r\n         <strong>String sqlStr = \"select * from books where author = \" + \"'\" + request.getParameter(\"author\") + \"'\" + \" and qty &gt; 0 order by price desc\";<\/strong>\r\n \r\n         \/\/ Print an HTML page as the output of the query\r\n         out.println(\"&lt;html&gt;&lt;head&gt;&lt;title&gt;Query Response&lt;\/title&gt;&lt;\/head&gt;&lt;body&gt;\");\r\n         out.println(\"&lt;h3&gt;Thank you for your query.&lt;\/h3&gt;\");\r\n         out.println(\"&lt;p&gt;You query is: \" + sqlStr + \"&lt;\/p&gt;\"); \/\/ Echo for debugging\r\n         <strong>ResultSet rset = stmt.executeQuery(sqlStr);<\/strong>  \/\/ Send the query to the server\r\n \r\n         \/\/ Step 4: Process the query result set\r\n         int count = 0;\r\n         while(<strong>rset.next()<\/strong>) {\r\n            \/\/ Print a paragraph &lt;p&gt;...&lt;\/p&gt; for each record\r\n            out.println(\"&lt;p&gt;\" + <strong>rset.getString(\"author\")<\/strong>\r\n                 + \", \" + <strong>rset.getString(\"title\")<\/strong>\r\n                 + \", $\" + <strong>rset.getDouble(\"price\")<\/strong> + \"&lt;\/p&gt;\");\r\n            count++;\r\n         }\r\n         out.println(\"&lt;p&gt;==== \" + count + \" records found =====&lt;\/p&gt;\");\r\n         out.println(\"&lt;\/body&gt;&lt;\/html&gt;\");\r\n     } catch (SQLException ex) {\r\n        ex.printStackTrace();\r\n     } finally {\r\n        out.close();  \/\/ Close the output writer\r\n        try {\r\n           \/\/ Step 5: Close the resources\r\n           if (stmt != null) <strong>stmt.close()<\/strong>;\r\n           if (conn != null) <strong>conn.close()<\/strong>;\r\n        } catch (SQLException ex) {\r\n           ex.printStackTrace();\r\n        }\r\n     }\r\n   }\r\n}<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h5>Step 7(e) Configure the Request URL for the Servlet<\/h5>\n<p>Open the configuration file &#8220;<code>web.xml<\/code>&#8221; of your application &#8220;<code>hello<\/code>&#8221; that you have created earlier for the <code>HelloServlet<\/code>, i.e., &#8220;<code>&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF\\web.xml<\/code>&#8220;. Add the lines that are shown in red at the correct locations.<\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31<\/pre>\n<\/td>\n<td>\n<pre>&lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\"?&gt;\r\n&lt;web-app version=\"3.0\"\r\n  xmlns=\"http:\/\/java.sun.com\/xml\/ns\/javaee\"\r\n  xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n  xsi:schemaLocation=\"http:\/\/java.sun.com\/xml\/ns\/javaee http:\/\/java.sun.com\/xml\/ns\/javaee\/web-app_3_0.xsd\"&gt;\r\n \r\n   &lt;!-- To save as \"hello\\WEB-INF\\web.xml\" --&gt;\r\n \r\n   &lt;servlet&gt;\r\n      &lt;servlet-name&gt;HelloWorld&lt;\/servlet-name&gt;\r\n      &lt;servlet-class&gt;HelloServlet&lt;\/servlet-class&gt;\r\n   &lt;\/servlet&gt;\r\n \r\n   &lt;servlet&gt;\r\n      &lt;servlet-name&gt;<strong>UserQuery<\/strong>&lt;\/servlet-name&gt;\r\n      &lt;servlet-class&gt;<strong>QueryServlet<\/strong>&lt;\/servlet-class&gt;\r\n   &lt;\/servlet&gt;\r\n \r\n   <strong>&lt;!-- Note: All &lt;servlet&gt; elements MUST be grouped together and placed IN FRONT of the &lt;servlet-mapping&gt; elements --&gt;<\/strong>\r\n \r\n   &lt;servlet-mapping&gt;\r\n      &lt;servlet-name&gt;HelloWorld&lt;\/servlet-name&gt;\r\n      &lt;url-pattern&gt;\/sayhello&lt;\/url-pattern&gt;\r\n   &lt;\/servlet-mapping&gt;\r\n \r\n   &lt;servlet-mapping&gt;\r\n      &lt;servlet-name&gt;<strong>UserQuery<\/strong>&lt;\/servlet-name&gt;\r\n      &lt;url-pattern&gt;<strong>\/doquery<\/strong>&lt;\/url-pattern&gt;\r\n   &lt;\/servlet-mapping&gt;\r\n&lt;\/web-app&gt;<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The above lines configure the following URL to invoke <code>QueryServlet<\/code>:<\/p>\n<pre>http:\/\/localhost:9999\/hello<strong>\/doquery<\/strong><\/pre>\n<h5>Step 7(f) Invoke the Servlet from the Client-Side Form<\/h5>\n<p>Issue the following URL to browse the HMTL form &#8220;<code>querybook.html<\/code>&#8221; that you have created earlier:<\/p>\n<pre>http:\/\/localhost:9999\/hello\/<strong>querybook.html<\/strong><\/pre>\n<p>Select an author (e.g., &#8220;Tan Ah Teck&#8221;) and click the submit button, which activates the following URL coded in the <code>&lt;form&gt;<\/code>&#8216;s &#8220;<code>action<\/code>&#8221; attribute, together with the name=value pair:<\/p>\n<pre>http:\/\/localhost:9999\/hello\/<strong>doquery?author=Tan+Ah+Teck<\/strong><\/pre>\n<p>This URL &#8220;\/<code>doquery<\/code>&#8221; triggers <code>QueryServlet<\/code>. The <code>QueryServlet<\/code> retrieves the name=value pair of &#8220;<code>author=Tan+Ah+Teck<\/code>&#8220;. Inside the <code>QueryServlet<\/code>, the method <code>request.getParameter(\"author\")<\/code> returns &#8220;<code>Tan Ah Teck<\/code>&#8220;, which is inserted into the SQL <code>SELECT<\/code> command to query the database. The processed query result is then written to the client as an HTML document.<\/p>\n<p>&nbsp;<\/p>\n<p>(Skip Unless&#8230;) The likely errors are &#8220;404 File Not Found&#8221; and &#8220;500 Internal Server Error&#8221;. Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html#TomcatDebug\">How to debug<\/a>&#8221; Section.<\/p>\n<h4>2.9\u00a0\u00a0(Advanced) Deploying Servlet using @WebServlet (Servlet 3.0 on Tomcat 7)<\/h4>\n<p>Servlet 3.0, which is supported by Tomcat 7, introduces the <code>@WebServlet<\/code> annotation, which greatly simplifies the deployment of servlets. You no longer need to write the deployment descriptor in &#8220;<code>web.xml<\/code>&#8220;. Instead, you can use the <code>@WebServlet<\/code> annotation to specify the url mapping.<\/p>\n<p>For example, let us write a new servlet called <code>AnotherHelloServlet.java<\/code>, by modifying the <code>HelloServlet.java<\/code> written earlier, with url mapping of &#8220;<code>sayhi<\/code>&#8220;.<\/p>\n<table>\n<colgroup>\n<col \/>\n<col \/> <\/colgroup>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36<\/pre>\n<\/td>\n<td>\n<pre>\/\/ To save as \"&lt;TOMCAT_HOME&gt;\\webapps\\hello\\WEB-INF\\classes\\<strong>AnotherHelloServlet<\/strong>.java\"\r\nimport java.io.*;\r\nimport javax.servlet.*;\r\nimport javax.servlet.http.*;\r\n<strong>import javax.servlet.annotation.*;<\/strong>\r\n \r\n<strong>@WebServlet(\"\/sayhi\")<\/strong>\r\npublic class <strong>AnotherHelloServlet<\/strong> extends HttpServlet {\r\n   @Override\r\n   public void doGet(HttpServletRequest request, HttpServletResponse response)\r\n         throws IOException, ServletException {\r\n \r\n      \/\/ Set the response MIME type\r\n      response.setContentType(\"text\/html;charset=UTF-8\");\r\n      \/\/ Allocate a output writer to write the response message into the network socket\r\n      PrintWriter out = response.getWriter();\r\n \r\n      \/\/ Write the response message, in an HTML page\r\n      try {\r\n         out.println(\"&lt;html&gt;\");\r\n         out.println(\"&lt;head&gt;&lt;title&gt;Hello, World&lt;\/title&gt;&lt;\/head&gt;\");\r\n         out.println(\"&lt;body&gt;\");\r\n         out.println(\"&lt;h1&gt;Hello world, again!&lt;\/h1&gt;\");  \/\/ says Hello\r\n         \/\/ Echo client's request information\r\n         out.println(\"&lt;p&gt;Request URI: \" + request.getRequestURI() + \"&lt;\/p&gt;\");\r\n         out.println(\"&lt;p&gt;Protocol: \" + request.getProtocol() + \"&lt;\/p&gt;\");\r\n         out.println(\"&lt;p&gt;PathInfo: \" + request.getPathInfo() + \"&lt;\/p&gt;\");\r\n         out.println(\"&lt;p&gt;Remote Address: \" + request.getRemoteAddr() + \"&lt;\/p&gt;\");\r\n         \/\/ Generate a random number upon each request\r\n         out.println(\"&lt;p&gt;A Random Number: &lt;strong&gt;\" + Math.random() + \"&lt;\/strong&gt;&lt;\/p&gt;\");\r\n         out.println(\"&lt;\/body&gt;&lt;\/html&gt;\");\r\n      } finally {\r\n         out.close();  \/\/ Always close the output writer\r\n      }\r\n   }\r\n}<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>In Line 7, the annotation <code>@WebServlet(\"\/sayhi\")<\/code> is used to declare the url mapping for this servlet, i.e., <code>http:\/\/localhost:9999\/hello\/sayhi<\/code>. There is no need to provide any more configuration in &#8220;<code>web.xml<\/code>&#8220;!<\/p>\n<h3 id=\"TomcatDebug\">3.\u00a0\u00a0How to Debug?<\/h3>\n<p>&#8220;Everything that can possibly go wrong will go wrong.&#8221;<\/p>\n<h5>Always&#8230;<\/h5>\n<ol>\n<li>Refresh your browser using <strong>Cntl-F5<\/strong> (instead of refresh button or simply F5) to get a fresh copy, instead of from the cache.<\/li>\n<li>You may re-start your Tomcat. You may also re-start your browser to clear the cache.<\/li>\n<li>Check your spelling! Always assume that all programs are case-sensitive. Don&#8217;t type, copy and paste if possible!<\/li>\n<li>If Tomcat can be started, but you cannot run your servlet. Goto the Tomcat&#8217;s home page (<code>http:\/\/localhost:9999<\/code>), and try to run the &#8220;servlets examples&#8221; to ensure that Tomcat is properly installed.<\/li>\n<li>Try accessing your application root, e.g., <code>http:\/\/localhost:9999\/hello<\/code>. You shall see the directory listing (if you have enabled the directory listing option in &#8220;<code>web.xml<\/code>&#8221; in Step 3(b)).<\/li>\n<li>and MOST IMPORTANTLY &#8211; Find the <strong>ERROR MESSAGE<\/strong>!!!\n<ol>\n<li>Check the Error Messages on Tomcat&#8217;s Console. Most of the error messages have tens of lines. You need to scroll up slowly from the last message to look for the first-line of the error messages.<\/li>\n<li>Check the Tomcat&#8217;s log files, located at &#8220;<code>&lt;TOMCAT_HOME&gt;\\logs<\/code>&#8221; directory. &#8220;<code>catalina.yyyy-mm-dd.log<\/code>&#8221; shows the Tomcat&#8217;s startup messages. Also check the &#8220;<code>localhost.yyyy-mm-dd.log<\/code>&#8220;.<\/li>\n<\/ol>\n<\/li>\n<li>If things were running fine until the lightning strikes, ask yourself &#8220;what have I changes?&#8221;<\/li>\n<\/ol>\n<h5>(Firefox) Unable to Connect<br \/> (IE) Internet Explorer cannot display the webpage<br \/> (Chrome) Oops! Google Chrome could not connect to &#8230;<\/h5>\n<p>Cause: You are simply not connecting to your Tomcat.<\/p>\n<p>Solution:<\/p>\n<ol>\n<li>Check if your Tomcat server has been started?<\/li>\n<li>Check the hostname and port number, separated by a colon <code>':'<\/code>, of your URL (<code>http:\/\/localhost:9999\/...<\/code>).<\/li>\n<\/ol>\n<h5>Error 404 File Not Found<\/h5>\n<p>Cause: You have connected to your Tomcat. But Tomcat server cannot find the HTML file or Servlet that your requested.<\/p>\n<p>Solution:<\/p>\n<ol>\n<li>Check your spelling! The path is case-sensitive!<\/li>\n<li>For HTML file with URL <code>http:\/\/localhost:9999\/<em>xxxx<\/em>\/<em>filename<\/em>.html<\/code>:\n<ol>\n<li>Open Tomcat&#8217;s &#8220;<code>webapps<\/code>&#8221; directory, check if sub-directory &#8220;<em><code>xxxx<\/code><\/em>&#8221; exists. It is case-sensitive.<\/li>\n<li>Open the &#8220;<em><code>xxxx<\/code><\/em>&#8221; directory, check if &#8220;<code><em>filename<\/em>.html<\/code>&#8221; exists.<\/li>\n<\/ol>\n<\/li>\n<li>For Servlet with URL <code>http:\/\/localhost:9999\/<em>xxxx<\/em>\/<em>servletURL<\/em><\/code>:\n<ol>\n<li>Check the Tomcat&#8217;s console for error message. Your application cannot be deployed if you make a mistake in editing &#8220;<code>web.xml<\/code>&#8220;, which triggered many error messages.<\/li>\n<li>Check the Tomcat console to make sure that your application has been deployed.<\/li>\n<li>Open Tomcat&#8217;s &#8220;<code>webapps<\/code>&#8221; directory, check if sub-directory &#8220;<em><code>xxxx<\/code><\/em>&#8221; exists.<\/li>\n<li>Open the &#8220;<em><code>xxxx<\/code><\/em>&#8221; directory, check if sub-sub-directory &#8220;<code>WEB-INF<\/code>&#8221; (uppercase with a dash) exists.<\/li>\n<li>Open the &#8220;<code>WEB-INF<\/code>&#8220;, check if sub-sub-sub directory &#8220;classes&#8221; (lowercase, plural) exists.<\/li>\n<li>Open the configuration file &#8220;<code>WEB-INF\\web.xml<\/code>&#8220;:\n<ol>\n<li>Check that <em><code>servletURL<\/code><\/em> is defined in a <code>&lt;servlet-mapping&gt;<\/code> tag. Take note of the <em><code>name<\/code><\/em> in <code>&lt;servlet-name&gt;<\/code> tag.<\/li>\n<li>Based on the <em><code>name<\/code><\/em> noted, look for the matching <code>&lt;servlet-class&gt;<\/code> tag. Take note of the <em><code>ServletClassname<\/code><\/em>.<\/li>\n<li>Open &#8220;<code>WEB-INF\\classes<\/code>&#8220;, check if &#8220;<em><code>ServletClassname<\/code><\/em><code>.class<\/code>&#8221; that you noted exists (Note: It is &#8220;<code>.class<\/code>&#8220;, and NOT &#8220;<code>.java<\/code>&#8220;. You need to compile the &#8220;<code>.java<\/code>&#8221; to get the &#8220;<code>.class<\/code>&#8220;.)<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h5>Error 500 Internal Server Error<\/h5>\n<p>Error 500 should have triggered many error message in the Tomcat&#8217;s console. Go to the Tomcat&#8217;s console, find the error message. The error message spans tens of lines. You need to scroll up slowly to look for the <em>first line<\/em> of the error message. The error message should tell you the cuase of this error, e.g. SQL syntax error, wrong user\/password, etc.<\/p>\n<p>For database servlet, you may check the error messages at &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/ErrorMessages.html#JDBCErrors\">Common Errors in JDBC Programming<\/a>&#8220;.<\/p>\n<ul>\n<li>For &#8220;No suitable driver found&#8221; (Windows) or <code>NullPointerException<\/code> (Mac and Linux): Read Step 7(b) again, again, and again.<\/li>\n<\/ul>\n<h5>Error 505: GET (or POST) Method Not Supported<\/h5>\n<p>Check you servlet to make sure that you have defined a <code>doGet()<\/code> (or <code>doPost()<\/code>) method.<\/p>\n<h5>Others<\/h5>\n<p>This article is meant for advanced programmers who is interested to know more about Tomcat; or using Tomcat for production. For novices, read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_HowTo.html\">How to Install and Get Started with Tomcat<\/a>&#8220;.<\/p>\n<p>The <em>authoritative<\/em> source of information on Tomcat is the Tomcat&#8217;s documentation, available under Tomcat&#8217;s &#8220;<code>webapps\\docs<\/code>&#8221; directory. You may also refer to the Java Servlet, JSP and JSF specifications, as Tomcat is the <em>Reference Implementation<\/em> for these technologies.<\/p>\n<p>I shall assume that Tomcat is installed in <code>d:\\myproject\\tomcat<\/code>, and shall denote this directory as <code>$CATALINA_HOME<\/code> (Unix-style) or <code>%CATALINA_HOME%<\/code> (Windows-style). Catalina is the codename for Tomcat 5 and above.<\/p>\n<h3>Tomcat&#8217;s Architecture and the main configuration file &#8220;server.xml&#8221;<\/h3>\n<p>Tomcat is an HTTP server. Tomcat is also a container that can execute Java Servlet, and converting JavaServer Pages (JSP) and JavaServerFaces (JSF) to Java Servlet. Tomcat employs a hierarchical and modular architecture as illustrated:<\/p>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatArchitecture.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1498\" title=\"TomcatArchitecture\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/TomcatArchitecture.png\" alt=\"\" width=\"634\" height=\"324\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatArchitecture.png 634w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatArchitecture-300x153.png 300w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatArchitecture-150x76.png 150w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/TomcatArchitecture-400x204.png 400w\" sizes=\"(max-width: 634px) 100vw, 634px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Tomcat&#8217;s main configuration file is the &#8220;<code>server.xml<\/code>&#8220;, kept under the <code>$CATALINA_HOME\\conf<\/code> directory. The default &#8220;<code>server.xml<\/code>&#8221; is reproduced as follows (after removing the comments and some minor touch ups):<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<pre>1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38<\/pre>\n<\/td>\n<td>\n<pre>&lt;?xml version='1.0' encoding='utf-8'?&gt;\r\n&lt;<strong>Server<\/strong> port=\"8005\" shutdown=\"SHUTDOWN\"&gt;\r\n  &lt;Listener className=\"org.apache.catalina.core.JasperListener\" \/&gt;\r\n  &lt;Listener className=\"org.apache.catalina.core.AprLifecycleListener\" SSLEngine=\"on\" \/&gt;\r\n  &lt;Listener className=\"org.apache.catalina.core.JreMemoryLeakPreventionListener\" \/&gt;\r\n  &lt;Listener className=\"org.apache.catalina.mbeans.GlobalResourcesLifecycleListener\" \/&gt;\r\n  &lt;Listener className=\"org.apache.catalina.core.ThreadLocalLeakPreventionListener\" \/&gt;\r\n \r\n  &lt;GlobalNamingResources&gt;\r\n    &lt;Resource name=\"UserDatabase\" auth=\"Container\"\r\n              type=\"org.apache.catalina.UserDatabase\"\r\n              description=\"User database that can be updated and saved\"\r\n              factory=\"org.apache.catalina.users.MemoryUserDatabaseFactory\"\r\n              pathname=\"conf\/tomcat-users.xml\" \/&gt;\r\n  &lt;\/GlobalNamingResources&gt;\r\n \r\n  &lt;<strong>Service<\/strong> name=\"Catalina\"&gt;\r\n    &lt;<strong>Connector<\/strong> port=\"8080\" protocol=\"HTTP\/1.1\"\r\n               connectionTimeout=\"20000\"\r\n               redirectPort=\"8443\" \/&gt;\r\n    &lt;<strong>Connector<\/strong> port=\"8009\" protocol=\"AJP\/1.3\" redirectPort=\"8443\" \/&gt;\r\n \r\n    &lt;<strong>Engine<\/strong> name=\"Catalina\" defaultHost=\"localhost\"&gt;\r\n \r\n      &lt;Realm className=\"org.apache.catalina.realm.LockOutRealm\"&gt;\r\n        &lt;Realm className=\"org.apache.catalina.realm.UserDatabaseRealm\"\r\n               resourceName=\"UserDatabase\"\/&gt;\r\n      &lt;\/Realm&gt;\r\n \r\n      &lt;<strong>Host<\/strong> name=\"localhost\"  appBase=\"webapps\"\r\n            unpackWARs=\"true\" autoDeploy=\"true\"&gt;\r\n        &lt;Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs\"\r\n               prefix=\"localhost_access_log.\" suffix=\".txt\"\r\n               pattern=\"%h %l %u %t &amp;quot;%r&amp;quot; %s %b\" \/&gt;\r\n      &lt;\/Host&gt;\r\n    &lt;\/Engine&gt;\r\n  &lt;\/Service&gt;\r\n&lt;\/Server&gt;<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>Server<\/h4>\n<p><code>Server<\/code> (Line 2) is top component, representing an instance of Tomcat.It can contains one or more <code>Services<\/code>, each with its own <code>Engines<\/code> and <code>Connectors<\/code>.<\/p>\n<pre>&lt;<strong>Server<\/strong> port=\"8005\" shutdown=\"SHUTDOWN\"&gt; ...... &lt;\/Server&gt;<\/pre>\n<h4>Listeners<\/h4>\n<p>The <code>Server<\/code> contains several <code>Listeners<\/code> (Lines 3-7). A <code>Listener<\/code> listens and responses to specific events.<\/p>\n<ul>\n<li>The <code>JasperListener<\/code> enables the <code>Jasper<\/code>JSP engine, and is responsible for re-compiling the JSP pages that have been updated.\n<pre>&lt;<strong>Listener<\/strong> className=\"org.apache.catalina.core.JasperListener\" \/&gt;<\/pre>\n<\/li>\n<li>The <code>GlobalResourcesLifecycleListener<\/code>enables the global resources, and makes possible the use of JNDI for accessing resources such as databases.\n<pre>&lt;<strong>Listener<\/strong> className=\"org.apache.catalina.mbeans.GlobalResourcesLifecycleListener\" \/&gt;<\/pre>\n<\/li>\n<\/ul>\n<h4>Global Naming Resources<\/h4>\n<p>The <code>&lt;GlobalNamingResources&gt;<\/code> element (Line 9-15) defines the JNDI (Java Naming and Directory Interface) resources, that allows Java software clients to discover and look up data and objects via a name.<\/p>\n<p>The default configuration defines a JNDI name called <code>UserDatabase<\/code> via the <code>&lt;Resource&gt;<\/code> element (Line 10-14), which is a memory-based database for user authentication loaded from &#8220;<code>conf\/tomcat-users.xml<\/code>&#8220;.<\/p>\n<pre>&lt;<strong>GlobalNamingResources<\/strong>&gt;\r\n  &lt;<strong>Resource<\/strong> name=\"<strong>UserDatabase<\/strong>\" auth=\"Container\"\r\n            type=\"org.apache.catalina.UserDatabase\"\r\n            description=\"User database that can be updated and saved\"\r\n            factory=\"org.apache.catalina.users.MemoryUserDatabaseFactory\"\r\n            pathname=\"<strong>conf\/tomcat-users.xml<\/strong>\" \/&gt;\r\n&lt;\/GlobalNamingResources&gt;<\/pre>\n<p>You can define other global resource JNDI such as MySQL database to implement connection pooling.<\/p>\n<h4>Services<\/h4>\n<p>A <code>Service<\/code> associates one or more <code>Connectors<\/code> to a <code>Engine<\/code>. The default configuration defines a <code>Service<\/code> called &#8220;<code>Catalina<\/code>&#8220;, and associates two <code>Connectors<\/code>: HTTP and AJP to the <code>Engine<\/code>.<\/p>\n<pre>&lt;<strong>Service<\/strong> name=\"Catalina\"&gt; ...... &lt;\/Service&gt;<\/pre>\n<h4>Connectors<\/h4>\n<p>A <code>Connector<\/code> is associated with a TCP port to handle communications between the <code>Service<\/code> and the clients. The default configuration defines two <code>Connectors<\/code>:<\/p>\n<ul>\n<li>HTTP\/1.1: Handle HTTP communication and enable Tomcat to be an HTTP server. Clients can issue HTTP requests to the server via this <code>Connector<\/code>, and receive the HTTP response messages.\n<pre>&lt;<strong>Connector<\/strong> port=\"8080\" protocol=\"HTTP\/1.1\" connectionTimeout=\"20000\" redirectPort=\"8443\" \/&gt;<\/pre>\n<p>The default chooses TCP port 8080 to run the Tomcat HTTP server, which is different from the default port number of 80 for HTTP production server. You can choose any number between 1024 to 65535, which is not used by any application, to run your Tomcat server.<br \/> The <code>connectionTimeout<\/code> attribute define the number of milliseconds this <code>connector<\/code> will wait, after accepting a connection, for the request URI line (request message) to be presented. The default is 20 seconds.<br \/> The <code>redirect<\/code> attribute re-directs the SSL requests to TCP port 8443.<\/p>\n<\/li>\n<li>AJP\/1.3: Apache JServ Protocol <code>connector<\/code>to handle communication between Tomcat server and Apache HTTP server.\n<pre>&lt;<strong>Connector<\/strong> port=\"8009\" protocol=\"AJP\/1.3\" redirectPort=\"8443\" \/&gt;<\/pre>\n<p>You could run Tomcat and Apache HTTP servers together, and let the Apache HTTP server handles static requests and PHP; while Tomcat server handles the Java Servlet\/JSP. Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/ApachePlusTomcat_HowTo.html\">How To Configure Tomcat to work with Apache<\/a>&#8220;.<\/p>\n<\/li>\n<\/ul>\n<h4>Containers<\/h4>\n<p>Tomcat refers to <code>Engine<\/code>, <code>Host<\/code>, <code>Context<\/code>, and <code>Cluster<\/code>, as <em>container<\/em>. The highest-level is <code>Engine<\/code>; while the lowest-level is <code>Context<\/code>. Certain components, such as <code>Realm<\/code> and <code>Valve<\/code>, can be placed in a container.<\/p>\n<h4>Engine<\/h4>\n<p>A <code>Engine<\/code> is the highest-level of a <em>container<\/em>. It can contains one or more <code>Hosts<\/code>. You could configure a Tomcat server to run on several <em>hostnames<\/em>, known as <em>virtual host<\/em>.<\/p>\n<pre>&lt;<strong>Engine<\/strong> name=\"Catalina\" defaultHost=\"localhost\"&gt;<\/pre>\n<p>The <code>Catalina Engine<\/code> receives HTTP requests from the HTTP connector, and direct them to the correct host based on the hostname\/IP address in the request header.<\/p>\n<h4>Realm<\/h4>\n<p>A <code>Realm<\/code> is a database of user, password, and role for authentication (i.e., access control). You can define <code>Realm<\/code> for any container, such as <code>Engine<\/code>, <code>Host<\/code>, and <code>Context<\/code>, and <code>Cluster<\/code>.<\/p>\n<pre>&lt;<strong>Realm<\/strong> className=\"org.apache.catalina.realm.LockOutRealm\"&gt;\r\n  &lt;Realm className=\"org.apache.catalina.realm.UserDatabaseRealm\" resourceName=\"<strong>UserDatabase<\/strong>\"\/&gt;\r\n&lt;\/Realm&gt;<\/pre>\n<p>The default configuration defines a <code>Realm<\/code> (<code>UserDatabaseRealm<\/code>) for the <code>Catalina Engine<\/code>, to perform user authentication for accessing this engine. It uses the JNDI name <code>UserDatabase<\/code> defined in the <code>GlobalNamingResources<\/code>.<\/p>\n<p>Besides the <code>UserDatabaseRealm<\/code>, there are: <code>JDBCRealm<\/code> (for authenticating users to connect to a relational database via the JDBC driver); <code>DataSourceRealm<\/code> (to connect to a <code>DataSource<\/code> via JNDI; <code>JNDIRealm<\/code> (to connect to an LDAP directory); and <code>MemoryRealm<\/code> (to load an XML file in memory).<\/p>\n<h4>Hosts<\/h4>\n<p>A <code>Host<\/code> defines a virtual host under the <code>Engine<\/code>, which can in turn support many <code>Contexts<\/code> (webapps).<\/p>\n<pre>&lt;<strong>Host<\/strong> name=\"localhost\" appBase=\"webapps\" unpackWARs=\"true\" autoDeploy=\"true\"&gt;<\/pre>\n<p>The default configuration define one host called <code>localhost<\/code>. The <code>appBase<\/code> attribute defines the base directory of all the webapps, in this case, <code>$CATALINA_HOME\\webapps<\/code>. By default, each webapp&#8217;s URL is the same as its <em>directory name<\/em>. For example, the default Tomcat installation provides four webapps: <code>docs<\/code>, <code>examples<\/code>, <code>host-manager<\/code> and <code>manager<\/code> under the <code>webapps<\/code> directory. The only exception is ROOT, which is identified by an empty string. That is, its URL is <code>http:\/\/localhost:8080\/<\/code>.<\/p>\n<p>The <code>unpackWARs<\/code> specifies whether WAR-file dropped into the <code>webapps<\/code> directory shall be unzipped. For <code>unpackWARs=\"false\"<\/code>, Tomcat will run the application from the WAR-file directly, without unpacking, which could mean slower execution.<\/p>\n<p>The <code>autoDeploy<\/code> attribute specifies whether to deploy application dropped into the <code>webapps<\/code> directory automatically.<\/p>\n<h4>Cluster<\/h4>\n<p>Tomcat supports server clustering. It can replicate sessions and context attributes across the clustered server. It can also deploy a WAR-file on all the cluster.<\/p>\n<h4>Valve<\/h4>\n<p>A <code>Valve<\/code> can intercept HTTP requests before forwarding them to the applications, for pre-processing the requests. A <code>Valve<\/code> can be defined for any container, such as <code>Engine<\/code>, <code>Host<\/code>, and <code>Context<\/code>, and <code>Cluster<\/code>.<\/p>\n<p>In the default configuration, the <code>AccessLogValve<\/code> intercepts an HTTP request and creates a log entry in the log file, as follows:<\/p>\n<pre>&lt;Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs\"\r\n       prefix=\"localhost_access_log.\" suffix=\".txt\"\r\n       pattern=\"%h %l %u %t &amp;quot;%r&amp;quot; %s %b\" \/&gt;<\/pre>\n<p>Other valves include:<\/p>\n<ul>\n<li><code>RemoteAddrValve<\/code>: which blocks requests from certain IP addresses,<\/li>\n<li><code>RemoteHostValve<\/code>: which blocks request based on hostnames,<\/li>\n<li><code>RequestDumperValve<\/code>: which logs details of the requests,<\/li>\n<li><code>SingleSignOn<\/code> Valve: when placed under a <code>&lt;host&gt;<\/code>, allows single sign-on to access all the webapp under the host.<\/li>\n<\/ul>\n<h4>Context (Application or Webapp)<\/h4>\n<p>A <em>web context<\/em> is a single <em>web application<\/em> (<em>webapp<\/em>). It is the lowest-level container, that you can define components such as <code>Realm<\/code> and <code>Valve<\/code>. By default, all webapps are kept under the <code>$CATALINA_HOME\\webapps<\/code> directory (as configured in the <code>&lt;host&gt;<\/code> element <code>appBase<\/code> attribute.<\/p>\n<p>A Java webapp may contain many types of files, such as HTML, CSS, Scripts, images, JSP, servlet, utility classes, external library jar-files. A Java webapp must follow a strict <em>directory structure<\/em> as depicted in the Servlet\/JSP specifications. This enables deployment in a Java-capable web server (such as Apache Tomcat and Glassfish). The resources must be kept in the correct directories and sub-directories.<\/p>\n<p>The URL of a webapp, by default, is the same as the <em>base directory name<\/em> (or <em>context root<\/em>) of the webapp.<\/p>\n<h5>Webapp&#8217;s Directory Structure<\/h5>\n<p>The directory structure of a webapp is as follows:<\/p>\n<p><a href=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/WebappDirectoryStructure.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1499\" title=\"WebappDirectoryStructure\" src=\"http:\/\/rmohan.com\/wp-content\/uploads\/2012\/09\/WebappDirectoryStructure.png\" alt=\"\" width=\"264\" height=\"388\" srcset=\"https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/WebappDirectoryStructure.png 264w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/WebappDirectoryStructure-204x300.png 204w, https:\/\/mohan.sg\/wp-content\/uploads\/2012\/09\/WebappDirectoryStructure-102x150.png 102w\" sizes=\"(max-width: 264px) 100vw, 264px\" \/><\/a><\/p>\n<p>&#8220;<em><code>ContextRoot<\/code><\/em>&#8220;: contains the resources that are visible and accessible by the web clients, such as HTML, CSS, Scripts and images. These resources will be delivered to the clients <em>as it is<\/em>. You could create sub-directories such as <code>images<\/code>, <code>css<\/code> and <code>scripts<\/code>, to further categories the various resources.<\/p>\n<ul>\n<li>&#8220;<code><em>ContextRoot<\/em>\\WEB-INF<\/code>&#8220;: This directory, although under the context root, is NOT visible to the web users. In other words, it is NOT accessible by the clients directly (for security reason). This is where you keep your application-specific configuration files such as &#8220;<code>web.xml<\/code>&#8220;. It&#8217;s sub-directories contain program classes, source files, and libraries.<\/li>\n<li>&#8220;<code><em>ContextRoot<\/em>\\WEB-INF\\src<\/code>&#8220;: Keeps the Java program source files. It is optional but a good practice to separate the source files and classes to facilitate deployment.<\/li>\n<li>&#8220;<code><em>ContextRoot<\/em>\\WEB-INF\\classes<\/code>&#8220;: Keeps the Java classes (compiled from the source codes). Classes defined in packages must be kept according to the Java package directory structure.<\/li>\n<li>&#8220;<code><em>ContextRoot<\/em>\\WEB-INF\\lib<\/code>&#8220;: Keeps the libraries (jar-files), which are provided by other packages, specific and available to this webapp only.<\/li>\n<li>&#8220;<code><em>ContextRoot<\/em>\\META-INF\\<\/code>&#8220;: This is also a hidden directory, to keep resources and configurations (e.g., &#8220;<code>context.xml<\/code>&#8220;) related to the server. In contrast, &#8220;<code>WEB-INF<\/code>&#8221; is for resources related to this web application, independent of the server.<\/li>\n<\/ul>\n<h5>Webapp-Specific Configuration Files<\/h5>\n<p>These are the configuration files specific to a webapp: (a) <code>WEB-INF\\web.xml<\/code>; (b) <code>META-INF\\context.xml<\/code>.<\/p>\n<p>You can configure a webapp in many ways: (a) Write a <code>&lt;context&gt;<\/code> element in <code>server.xml<\/code> under <code>&lt;Host&gt;<\/code> element, (b) <code><em>contextRoot<\/em>\\META-INF\\context.xml<\/code>, and (c) <code>conf\\Catalina\\localhost\\<em>webapp<\/em>.xml<\/code>, and (d) <code>conf\\context.xml<\/code>. See &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_More.html#ContextRootURL\">Setting the Context Root Directory and Request URL of a Webapp<\/a>&#8220;.<\/p>\n<h3>Tomcat&#8217;s Directory Structure<\/h3>\n<p>Tomcat installation provides these directories:<\/p>\n<ul>\n<li><code><strong>bin<\/strong><\/code>: for Tomcat&#8217;s binary codes.<\/li>\n<li><code><strong>conf<\/strong><\/code>: global configuration applicable to all the webapps. The default installation provides:\n<ul>\n<li>One policy file: <code>catalina.policy<\/code> for specifying security policy.<\/li>\n<li>Two properties files: <code>catalina.properties<\/code> and <code>logging.properties<\/code>,<\/li>\n<li>Four configuration files: <code>server.xml<\/code> (Tomcat main configuration file), <code>web.xml<\/code> (global web application deployment descriptors), <code>context.xml<\/code> (global Tomcat-specific configuration options) and <code>tomcat-users.xml<\/code> (a database of user, password and role for authentication and access control).<\/li>\n<\/ul>\n<p>The <code>conf<\/code> also contain a sub-directory for each engine, e.g., <code>Catalina<\/code>, which in turn contains a sub-sub-directory for each of its hosts, e.g., <code>localhost<\/code>. You can place the host-specific context information (similar to <code>context.xml<\/code>, but named as <em><code>webapp<\/code><\/em><code>.xml<\/code> for each webapp under the host).<\/p>\n<\/li>\n<li><code><strong>lib<\/strong><\/code>: Keeps the JAR-file that are available to all webapps. The default installation include <code>servlet-api.jar<\/code>, <code>jasper.jar<\/code> (JSP), <code>jasper-el.jar<\/code> (EL). You may also keep the MySQL JDBC driver (<code>mysql-connector-java-5.1.xx-bin.jar<\/code>), and JSTL (<code>jstl.jar<\/code> and <code>standard.jar<\/code>) here.<\/li>\n<li><code><strong>logs<\/strong><\/code>: contains the engine logfile <code>Catalina.yyyy-mm-dd.log<\/code>, host logfile <code>localhost.yyyy-mm-dd.log<\/code>, and other application logfiles such as <code>manger<\/code> and <code>host-manager<\/code>. The access log (created by the <code>AccessLogValve<\/code>) is also kept here.<\/li>\n<li><code><strong>temp<\/strong><\/code>: temporary files used by Tomcat.<\/li>\n<li><code><strong>webapps<\/strong><\/code>: the default <code>appBase<\/code> &#8211; web applications base directory of the host <code>localhost<\/code>.<\/li>\n<li><code><strong>work<\/strong><\/code>: contains the translated servlet source files and classes of JSP\/JSF. Organized in hierarchy of engine name (<code>Catalina<\/code>), host name (<code>localhost<\/code>), webapp name, followed by the Java classes package structure.<\/li>\n<\/ul>\n<h3>Other Configuration Files: web.xml, context.xml, tomcat-users.xml<\/h3>\n<p>[TODO]<\/p>\n<h3>Some Configuration Options<\/h3>\n<p>They are so many things that you can configured in Tomcat. I describe some of the configurations that I found useful in this section.<\/p>\n<h4>Enabling Directory Listing<\/h4>\n<p>When the request URL refers to a directory instead of a file, e.g., <code>http:\/\/<em>host<\/em>:<em>port<\/em>\/hello\/<\/code>, you can configure Tomcat to serve the directory listing, or a <em>welcome file<\/em>, or issue error &#8220;404 Page Not Found&#8221;. Enabling directory listing is handy for test server but NOT desire for production server (as it reveal the directory structure and expose the entire directory hierarchy).<\/p>\n<h5>Enabling Directory Listing for ALL Webapps<\/h5>\n<p>To enable directory listing for all the web applications, you could modify the <code>$CATALINA_HOME\\conf\\web.xml<\/code>, by changing &#8220;<code>listings<\/code>&#8221; from &#8220;<code>false<\/code>&#8221; to &#8220;<code>true<\/code>&#8221; for the &#8220;<code>default<\/code>&#8221; servlet, as follows:<\/p>\n<pre>&lt;!-- The default servlet for all web applications, that serves static     --&gt;\r\n&lt;!-- resources.  It processes all requests that are not mapped to other   --&gt;\r\n&lt;!-- servlets with servlet mappings.                                      --&gt;\r\n&lt;servlet&gt;\r\n  &lt;servlet-name&gt;<strong>default<\/strong>&lt;\/servlet-name&gt;\r\n  &lt;servlet-class&gt;org.apache.catalina.servlets.<strong>DefaultServlet<\/strong>&lt;\/servlet-class&gt;\r\n  &lt;init-param&gt;\r\n    &lt;param-name&gt;debug&lt;\/param-name&gt;\r\n    &lt;param-value&gt;0&lt;\/param-value&gt;\r\n  &lt;\/init-param&gt;\r\n  &lt;init-param&gt;\r\n    &lt;param-name&gt;<strong>listings<\/strong>&lt;\/param-name&gt;\r\n    &lt;param-value&gt;<strong>true<\/strong>&lt;\/param-value&gt;\r\n  &lt;\/init-param&gt;\r\n  &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;\r\n&lt;\/servlet&gt;\r\n    \r\n&lt;!-- The mapping for the default servlet --&gt;\r\n&lt;servlet-mapping&gt;\r\n  &lt;servlet-name&gt;<strong>default<\/strong>&lt;\/servlet-name&gt;\r\n  &lt;url-pattern&gt;<strong>\/<\/strong>&lt;\/url-pattern&gt;\r\n&lt;\/servlet-mapping&gt;\r\n   \r\n&lt;!-- ==================== Default Welcome File List ===================== --&gt;\r\n&lt;!-- When a request URI refers to a directory, the default servlet looks  --&gt;\r\n&lt;!-- for a \"welcome file\" within that directory and, if present,          --&gt;\r\n&lt;!-- to the corresponding resource URI for display.  If no welcome file   --&gt;\r\n&lt;!-- is present, the default servlet either serves a directory listing,   --&gt;\r\n&lt;!-- or returns a 404 status, depending on how it is configured.          --&gt;\r\n&lt;welcome-file-list&gt;\r\n  &lt;welcome-file&gt;<strong>index.html<\/strong>&lt;\/welcome-file&gt;\r\n  &lt;welcome-file&gt;<strong>index.htm<\/strong>&lt;\/welcome-file&gt;\r\n  &lt;welcome-file&gt;<strong>index.jsp<\/strong>&lt;\/welcome-file&gt;\r\n&lt;\/welcome-file-list&gt;\r\n<\/pre>\n<p>The above configuration maps URL &#8220;<code>\\<\/code>&#8221; (root directory of the web context) (in <code>&lt;url-pattern&gt;<\/code>) to Java class <code>DefaultServlet<\/code> (in <code>&lt;servlet-class&gt;<\/code>) via the common servlet name of <code>default<\/code> (in <code>&lt;servlet-name&gt;<\/code>). We enable directory listing by changing the servlet&#8217;s initialization parameter <code>listings<\/code> to <code>true<\/code>.<\/p>\n<p>If a user requests for a directory, and the directory listing is enabled and it contains one of the files in the <code>&lt;welcome-file&gt;<\/code> list, the welcome file will be served; otherwise, the directory listing will be served. On the other hand, if a directory request is received and the directory listing is not enabled, the server returns an error &#8220;404 Page Not Found&#8221;.<\/p>\n<h5>Enabling Directory Listing for a particular Webapp<\/h5>\n<p>If you wish to allow directory listing of a particular web application only, you could disable the directory listing in &#8220;<code>$CATALINA_HOME\\conf\\web.xml<\/code>&#8221; globally, and define the following <code>&lt;servlet&gt;<\/code> and <code>&lt;servlet-mapping&gt;<\/code> in your application-specific <code>WEB-INF\\web.xml<\/code>, as follows. You need to use another <code>&lt;servlet-name&gt;<\/code> in place of <code>DefaultServlet<\/code>.<\/p>\n<pre>&lt;servlet&gt;\r\n  &lt;servlet-name&gt;<strong>DirectoryListing<\/strong>&lt;\/servlet-name&gt;\r\n  &lt;servlet-class&gt;org.apache.catalina.servlets.DefaultServlet&lt;\/servlet-class&gt;\r\n  &lt;init-param&gt;\r\n    &lt;param-name&gt;debug&lt;\/param-name&gt;\r\n    &lt;param-value&gt;0&lt;\/param-value&gt;\r\n  &lt;\/init-param&gt;\r\n  &lt;init-param&gt;\r\n    &lt;param-name&gt;<strong>listings<\/strong>&lt;\/param-name&gt;\r\n    &lt;param-value&gt;<strong>true<\/strong>&lt;\/param-value&gt;\r\n  &lt;\/init-param&gt;\r\n&lt;\/servlet&gt;\r\n   \r\n&lt;servlet-mapping&gt;\r\n  &lt;servlet-name&gt;<strong>DirectoryListing<\/strong>&lt;\/servlet-name&gt;\r\n  &lt;url-pattern&gt;<strong>\/<\/strong>&lt;\/url-pattern&gt;\r\n&lt;\/servlet-mapping&gt;<\/pre>\n<h4>Automatic Servlet Reload<\/h4>\n<p>To enable automatic servlet reload (whenever a servlet is re-compiled), you need to specify <code>&lt;Context <strong>reloadable=\"true\"<\/strong>&gt;...&lt;\/Context&gt;<\/code>, in &#8220;<code>$CATALINA_HOME\\conf\\context.xml<\/code>&#8221; for all web applications, or the <code>&lt;Context&gt;<\/code> element in &#8220;<code>$CATALINA_HOME\\conf\\server.xml<\/code>&#8221; for a particular web application.<\/p>\n<p>The following messages appear on the Tomcat&#8217;s console if you re-compile a servlet:<\/p>\n<pre>XXX X, XXXX XX:XX:XX XX org.apache.catalina.core.StandardContext reload\r\nINFO: <strong>Reloading Context with path [\/hello] has started<\/strong>\r\nXXX X, XXXX XX:XX:XX XX org.apache.catalina.core.StandardContext reload\r\nINFO: <strong>Reloading Context with path [\/hello] is completed<\/strong><\/pre>\n<p>Enabling automatic servlet reload is handy during application development, but it requires significant runtime overhead to listen to the changes, and is not recommended for production systems. Instead, you could use the &#8220;<code>manager<\/code>&#8221; to trigger reloads on demand.<\/p>\n<h4>Setting the Context Root Directory and Request URL of a Webapp<a name=\"ContextRootURL\"><\/a>\u00a0<\/h4>\n<p>A server could run many web applications. A webapp is also called a <em>web context<\/em>. The <em>context root<\/em> (or <em>document base directory<\/em>) refers to the base directory of a webapp. They are a few ways to configure a context root and its request URL of a webapp:<\/p>\n<ol>\n<li>(RECOMMENDED) Create a directory under <code>$CATALINA_HOME\\webapps<\/code> for your webapp. A context will be created with request URL set to the name of the directory. For example, if you create a directory called &#8220;<code>hello<\/code>&#8221; under Tomcat&#8217;s &#8220;<code>webapps<\/code>&#8220;. This application can be accessed by web users via URL <code>http:\/\/<em>host<\/em>:<em>port<\/em>\/hello<\/code>.<br \/> To change the request URL of the webapp, create a &#8220;<code>context.xml<\/code>&#8221; configuration file, as follows, and place it under &#8220;<em><code>ContextRoot<\/code><\/em><code>\\META-INF<\/code>&#8220;:\n<pre>&lt;Context path=\"\/<em>yourURLPath<\/em>\" \/&gt;<\/pre>\n<\/li>\n<li>Alternatively, you can write a <code>&lt;Context&gt;<\/code> element in <code>$CATALINA_HOME\\conf\\server.xml<\/code>, under the <code>&lt;Host&gt;<\/code>element. You can specify both the URL and the base directory. For example,\n<pre>        ......\r\n        ......\r\n        &lt;Context path=\"\/ws\" docBase=\"d:\/workshop\" reloadable=\"true\"&gt;\r\n        &lt;\/Context&gt;\r\n      &lt;\/Host&gt;\r\n    &lt;\/Engine&gt;\r\n  &lt;\/Service&gt;\r\n&lt;\/Server&gt;<\/pre>\n<p>In the above example, we define a web context with URL &#8220;<code>\/ws<\/code>&#8220;, with context root (<code>docBase<\/code> or document base directory) at &#8220;<code>d:\\workshop<\/code>&#8220;. This application can be accessed via URL <code>http:\/\/<em>host<\/em>:<em>port<\/em><strong>\/ws<\/strong><\/code>.<br \/>Take note that:<\/p>\n<ul>\n<li>The configuration creates a <em>mapping<\/em> from the &#8220;URL Path&#8221; issued by the web users to the &#8220;document base directory&#8221; in the server&#8217;s file system, where you store your webapp resources.<\/li>\n<li>Place the <code>&lt;Context&gt;<\/code> element before the ending tag of the <code>&lt;Host&gt;<\/code> element.<\/li>\n<li>Use Unix-style forward slash <code>'\/'<\/code> as the <em>directory separator<\/em> in the configuration file, instead of Window-style back slash <code>'\\'<\/code>.<\/li>\n<li>The attribute <code>reloadable=\"true\"<\/code> asks Tomcat to monitor your servlets for changes, and automatically reload the servlets if changes is detected. This is handy for a development system, but inefficient in a production system.<\/li>\n<\/ul>\n<\/li>\n<li>Write a configuration file with a <code>&lt;Context&gt;<\/code> element and place it under Tomcat&#8217;s &#8220;<code>conf\\Catalina\\localhost<\/code>&#8220;. For example, suppose we wish to create a webapp with URL &#8220;<code>hello<\/code>&#8221; in base directory &#8220;<code>d:\\myproject\\myHello<\/code>&#8220;, create the following file &#8220;<code>hello.xml<\/code>&#8220;:\n<pre>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;Context docBase=\"D:\\myproject\\myHello\" path=\"\/hello\" \/&gt;<\/pre>\n<\/li>\n<\/ol>\n<h4>Changing the Default &#8220;webapps&#8221; Directory<\/h4>\n<p>The <em>default<\/em> directory for deploying web applications is <code>$CATALINA_HOME\\webapps<\/code>. You could change the default by modifying the configuration file <code>\"conf\\server.xml\"<\/code> <code>&lt;Host&gt;<\/code> element&#8217;s &#8220;<code>appBase<\/code>&#8221; attribute as follows:<\/p>\n<pre>&lt;Host name=\"localhost\" <strong>appBase=\"webapps\"<\/strong>\r\n      unpackWARs=\"true\" autoDeploy=\"true\"\r\n      xmlValidation=\"false\" xmlNamespaceAware=\"false\"&gt;\r\n   ......\r\n&lt;\/host&gt;<\/pre>\n<h3>Deploying a Web Application in a WAR file<a id=\"TomcatWar\" name=\"TomcatWar\"><\/a><\/h3>\n<p>You could use the JDK&#8217;s <code>jar<\/code> utility to &#8220;zip&#8221; up all the files of a web application to produce a so-called WAR (Web Application Archive) file for deployment, or distribution.<\/p>\n<pre>.... Change current directory to the web application's context root<em> contextRoot<\/em>&gt; <strong>jar cvf test.war .<\/strong><\/pre>\n<p>Drop the <code>test.war<\/code> into <code>$CATALINA_HOME\\webapps<\/code>. A context called <code>test<\/code> will be created automatically. You can access the web application via URL <code>http:\/\/<em>host<\/em>:<em>port<\/em>\/<strong>test<\/strong><\/code>.<\/p>\n<p>Tomcat actually unpacks the <code>test.war<\/code> into a &#8220;<code>test<\/code>&#8221; directory in <code>$CATALINA_HOME\\webapps<\/code>. You need to remove this directory, if you reload a new version.<\/p>\n<h3>Running Tomcat as a Windows Service<a id=\"TomcatService\" name=\"TomcatService\"><\/a><\/h3>\n<p>This section is applicable for Windows. You need to download the Windows-specific version of Tomcat (from Tomcat&#8217;s download, choose 32-bit or 64-bit Window zip, e.g., <code>apache-tomcat-7.0.2-windows-x86.zip<\/code>).<\/p>\n<p>Read &#8220;Windows service How-To&#8221; in the Tomcat documentation (<code>$CATALINA_HOME\\webapps\\docs\\windows-service-howto.html<\/code>).<\/p>\n<p>In a production environment, it is more convenient to run Tomcat as a <em>service<\/em>, so that it can start automatically whenever the system is started (or re-start automatically after an unexpected interruption).<\/p>\n<p>To install Tomcat as a service, start a CMD shell (with administrator right) and run the <code>$CATALINA_HOME\\bin\\service.bat<\/code> with <code>install<\/code> option:<\/p>\n<pre>... Change directory to $CATALINA_HOME\\bin ...\r\n$CATALINA_HOME\\bin&gt; <strong>service install<\/strong>\r\nInstalling the service 'Tomcat7' ...\r\n......\r\nThe service 'Tomcat7' has been installed.<\/pre>\n<p>The Tomcat service called &#8220;Apache Tomcat 7&#8221; is installed and will start automatically whenever the system is started. Check the &#8220;Services&#8221; under &#8220;Control Panel&#8221; ? &#8220;Administrative Tools&#8221;.<\/p>\n<p>A GUI application called <code>Tomcat7w<\/code> is available for monitoring and configuring Tomcat services. Launch <code>Tomcat7w<\/code>:<\/p>\n<pre>$CATALINA_HOME\\bin&gt; <strong>Tomcat7w<\/strong><\/pre>\n<p>You could put the Tomcat icon in the system tray via the MS (Monitor Service) option:<\/p>\n<pre>$CATALINA_HOME\\bin&gt; <strong>Tomcat7w \/\/MS\/\/<\/strong><\/pre>\n<p>You can start\/stop the Tomcat service now via:<\/p>\n<ol>\n<li><code>Tomcat7w<\/code>;<\/li>\n<li>&#8220;Control Panel&#8221; ? &#8220;Administrator Tools&#8221; ? &#8220;Services&#8221; ? &#8220;Apache Tomcat 7&#8221; ? &#8220;Start&#8221;;<\/li>\n<li>From CMD shell, Issue &#8220;<code>net<\/code>&#8221; command:\n<pre>prompt&gt; <strong>net start tomcat7<\/strong>\r\nThe Apache Tomcat 7 service is starting..\r\nThe Apache Tomcat 7 service was started successfully.\r\n......\r\n......\r\nprompt&gt; <strong>net stop <strong>tomcat7<\/strong><\/strong>\r\nThe Apache Tomcat 7 service is stopping..\r\nThe Apache Tomcat 7 service was stopped successfully.<\/pre>\n<\/li>\n<\/ol>\n<p>To uninstall Tomcat Service, run the <code>$CATALINA_HOME\\bin\\service.bat<\/code> with <code>remove<\/code> option:<\/p>\n<pre>$CATALINA_HOME\\bin&gt; <strong>service remove<\/strong>\r\nThe service 'Tomcat7' has been removed<\/pre>\n<p>A flip side of running Tomcat as a service is you need to read the error messages from <code>$CATALINA_HOME\\logs<\/code> instead of the Tomcat console.<\/p>\n<h3>Tomcat&#8217;s Startup Script<a id=\"TomcatStartupScript\" name=\"TomcatStartupScript\"><\/a><\/h3>\n<p>To start tomcat server, you could invoke the batch file &#8220;<code>startup.bat<\/code>&#8221; (in directory &#8220;<code>$CATALINA_HOME\\bin<\/code>&#8220;, where <code>CATALINA_HOME<\/code> refers to the Tomcat installed directory). The &#8220;<code>startup.bat<\/code>&#8221; invokes &#8220;<code>catalina.bat start<\/code>&#8220;.<\/p>\n<p>Alternatively, you could call the &#8220;<code>catalina.bat<\/code>&#8221; directly, which provides more options of starting Tomcat. Enter &#8220;<code>catalina<\/code>&#8221; to view the options:<\/p>\n<pre>$CATALINA_HOME\/bin&gt; <strong>catalina<\/strong>\r\nUsing CATALINA_BASE:   D:\\xxx\\tomcat7.0.xx\r\nUsing CATALINA_HOME:   D:\\xxx\\tomcat7.0.xx\r\nUsing CATALINA_TMPDIR: D:\\xxx\\tomcat7.0.xx\\temp\r\nUsing JRE_HOME:        d:\\xxx\\jdk1.6\r\nUsage:  catalina ( commands ... )\r\ncommands:\r\n  debug             Start Catalina in a debugger\r\n  debug -security   Debug Catalina with a security manager\r\n  jpda start        Start Catalina under JPDA debugger\r\n  run               Start Catalina in the current window\r\n  run -security     Start in the current window with security manager\r\n  <strong>start Start Catalina in a separate window<\/strong>\r\n  start -security   Start in a separate window with security manager\r\n  stop              Stop Catalina\r\n  version           What version of tomcat are you running?<\/pre>\n<p>Study the source codes of &#8220;<code>Tomcat.bat<\/code>&#8221; and &#8220;<code>catalina.bat<\/code>&#8220;, if interested. Read <a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/CMD_HowTo.html\">&#8220;Command Shell &#8211; How to&#8221;<\/a> about the syntax of batch files. At times, I need to use these files (comment-out the &#8220;<code>ECHO OFF<\/code>&#8220;) to debug Tomcat&#8217;s startup problems.<\/p>\n<h3>Web Application Deployment Descriptors &#8211; &#8220;web.xml&#8221;<\/h3>\n<p>The &#8220;<code>web.xml<\/code>&#8221; contains the deployment descriptors. There are two sets of <code>web.xml<\/code>:<\/p>\n<ol>\n<li><code>$CATALINA_HOME\\conf\\web.xml<\/code>: applicable to ALL webapps.<\/li>\n<li><code><em>ContextRoot<\/em>\\WEB-INF\\web.xml<\/code>: applicable to the specific web context. It overrides the global setting, if any.<\/li>\n<\/ol>\n<p>The complete specification for &#8220;<code>web.xml<\/code>&#8221; can be found in the &#8220;Java Servlet Specification&#8221; under &#8220;Deployment Descriptor&#8221;.<\/p>\n<h3>Tomcat&#8217;s Manager<a name=\"TomcatManager\"><\/a><\/h3>\n<p>Read &#8220;Apache Tomcat &#8211; Manager App HOW-TO&#8221; @ &#8220;webapps\/docs\/manager-howto.html&#8221;.<\/p>\n<p>Tomcat webapp manager allows you to deploy a new web application; start, stop, reload or un-deploy an existing one, without having to shut down and restart the server.<\/p>\n<p>To enable Tomcat manager, edit &#8220;<code>$CATALINA_HOME\\conf\\<strong>tomcat-users.xml<\/strong><\/code>&#8221; to include a role called &#8220;<code>manager<\/code>&#8221; and a user with &#8220;<code>manager<\/code>&#8221; role.<\/p>\n<pre>&lt;role rolename=\"manager\"\/&gt;\r\n&lt;user username=\"tomcatmanager\" password=\"xxxx\" roles=\"manager,manager-script,admin\"\/&gt;<\/pre>\n<p>Use <code>http:\/\/localhost:8080\/manager\/html<\/code> to invoke manager web application.<\/p>\n<h3>Tomcat with SSL<a name=\"TomcatSSL\"><\/a>\u00a0<\/h3>\n<p>SSL, or Secure Socket Layer, allows web browsers and web servers to communicate over a secured connection. Tomcat provides built-in support for SSL. Before you attempt to turn on the SSL support, make sure that your tomcat is running fine for HTTP without SSL.<\/p>\n<p>Read:<\/p>\n<ul>\n<li>&#8220;SSL Configuration How-to&#8221; of Tomcat Documentation @ &#8220;<code>$CATALINA_HOME\\webapps\\docs\\ssl-howto.html<\/code>&#8220;.<\/li>\n<li>&#8220;keytool &#8211; Key and Certificate Management Tool&#8221; @ JDK documentation.<\/li>\n<\/ul>\n<p>The steps to turn on SSL support are:<\/p>\n<p><strong>Step 1<\/strong>: Check your JDK version. Tomcat&#8217;s SSL uses Java Secure Socket Extension (JSSE), which has been integrated into JDK since 1.4.<\/p>\n<p><strong>Step 2<\/strong>: Prepare the Tomcat&#8217;s server certificate, using the JDK&#8217;s key and certificate management tool called &#8220;<code>keytool<\/code>&#8221; (in &#8220;<code>$JAVA_HOME\\bin<\/code>&#8221; ), as follows:<\/p>\n<pre>&gt; <strong>keytool<\/strong>\r\n... display the help menu ...\r\n   \r\n&gt; <strong>keytool -genkey -alias tomcat -keyalg RSA -keystore d:\\tomcat\\conf\\.keystore<\/strong>\r\nEnter keystore password: <strong>xxxxxxxx<\/strong>\r\nRe-enter new password: <strong>xxxxxxxx<\/strong>\r\nWhat is your first and last name?\r\n  [Unknown]:\r\nWhat is the name of your organizational unit?\r\n  [Unknown]:\r\nWhat is the name of your organization?\r\n  [Unknown]:\r\nWhat is the name of your City or Locality?\r\n  [Unknown]:\r\nWhat is the name of your State or Province?\r\n  [Unknown]:\r\nWhat is the two-letter country code for this unit?\r\n  [Unknown]:\r\nIs CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?\r\n  [no]:  <strong>y<\/strong>\r\nEnter key password for &lt;tomcat&gt;\r\n        (RETURN if same as keystore password):<\/pre>\n<ul>\n<li>The &#8220;<code>-genkey<\/code>&#8221; option is used to generate a public-private key pair.\u00a0The public key is wrapped into an X.509 v1 self-signed certificate.\u00a0The certificate and the private key are stored in a new keystore entry identified by the alias.\u00a0In our case, the alias name must be &#8220;<code>tomcat<\/code>&#8220;.<\/li>\n<li>The &#8220;<code>-keyalg<\/code>&#8221; option specifies the key generation algorithm.\u00a0RSA public key algorithm is used in this case.<\/li>\n<li>The &#8220;<code>-keystore<\/code>&#8221; option specifies the name and location of the key store file.<\/li>\n<li>The password for <code>&lt;tomcat&gt;<\/code> must be the same as the keystore (i.e., hit enter for the last question).<\/li>\n<\/ul>\n<p><strong>Step 3<\/strong>: Enable SSL support for Tomcat. SSL is built into Tomcat. The Tomcat&#8217;s configuration file commented out the SSL configuration directive. Uncomment them by removing the <code>&lt;!--<\/code> and <code>--&gt;<\/code> around the SSL Coyote HTTP\/1.1 Connector as follows:<\/p>\n<pre>&lt;!-- Define a SSL HTTP\/1.1 Connector on port 8443\r\n     This connector uses the JSSE configuration, when using APR, the \r\n     connector should be using the OpenSSL style configuration\r\n     described in the APR documentation --&gt;\r\n&lt;Connector port=\"8443\" <strong>protocol=\"org.apache.coyote.http11.Http11Protocol\"<\/strong>\r\n     SSLEnabled=\"true\" maxThreads=\"150\" scheme=\"https\" secure=\"true\"\r\n     clientAuth=\"false\" sslProtocol=\"TLS\" \r\n     <strong>keystoreFile=\"d:\\tomcat\\conf\\.keystore\"<\/strong>\r\n     <strong>keystorePass=\"<em>passwordOfKeyStore<\/em>\"<\/strong> \/&gt;<\/pre>\n<p>Note that the SSL (or HTTPS) is running on port 8443 instead of its default port number 443.<\/p>\n<p>Add in the <code>keystoreFile<\/code> and <code>keyStorePass<\/code> attributes. The <code>keystoreFile<\/code> attribute specified the location of the keystore file. The <code>keyStorePass<\/code> provides the password for accessing the keystore file.<\/p>\n<p><strong>Step 4<\/strong>: Start your tomcat (run &#8220;<code>$CATALINA_HOME\\bin\\startup.bat<\/code>&#8220;). After that, start a web browser and issue an HTTPS request as follows:<\/p>\n<pre>https:\/\/localhost:8443\r\n<\/pre>\n<h3>User Authentication in Tomcat<a name=\"tomcat_auth\"><\/a>\u00a0<\/h3>\n<p>Read Tomcat documentation &#8220;Realm Configuration HOW-TO&#8221; (@ &#8220;<code>$CATALINA_HOME\\webapps\\docs\\realm-howto.html<\/code>&#8220;) and &#8220;Java EE 5 Tutorial&#8221;, Part IV &#8220;Services&#8221;, Chapters 28-30 on Security.<\/p>\n<p>In Information Security:<\/p>\n<ul>\n<li><em>Access control<\/em> deals with identifying which resources require protection, and which users (roles) are authorized to access the protected resources.<\/li>\n<li><em>Authentication<\/em> deals with verifying users&#8217; credential, i.e., ensuring the user is &#8220;who he said he is&#8221;. User&#8217;s credential is typically provided in the form of username\/password. Other means include biometrics (finger-prints, retina) and digital certificates.<\/li>\n<li><em>Confidentiality<\/em> deals with the encryption of the transmitted data over the network. This is often carried out via employing HTTP over SSL (Secure Socket Layer), known as HTTPS.<\/li>\n<li><em>Message Integrity<\/em>: message is not tempered during transmission (via message digest or hash).<\/li>\n<li><em>Non-repudiation<\/em>: If he\/she has sent a message, he\/she cannot deny (via public-key or digital certificate).<\/li>\n<\/ul>\n<p>In Tomcat&#8217;s web applications, a user is identified via username\/password. A user is assigned role(s) (e.g., manager, admin, user, etc). Tomcat grants access for web application to role(s), instead of individual users. A <em>realm<\/em> is a database or file, which contains user information such as username\/password, and roles.<\/p>\n<p>Tomcat supports the following types of realm:<\/p>\n<ul>\n<li><code> UserDatabaseRealm<\/code>: user information kept in a XML file &#8220;<code>conf\\tomcat-users.xml<\/code>&#8220;, accessed via JDNI (Java Naming and Directory Interface).<\/li>\n<li><code>JDBCRealm<\/code>: user information kept in a relational database such as MySQL, accessed via JDBC.<\/li>\n<li>others.<\/li>\n<\/ul>\n<p>You can used the <code>&lt;realm&gt;<\/code> element to configure a realm in &#8220;<code>conf\\server.xml<\/code>&#8220;. <code>&lt;realm&gt;<\/code> element can be placed in <code>&lt;engine&gt;<\/code>, <code>&lt;host&gt;<\/code>, or <code>&lt;context&gt;<\/code>, which determines the <em>scope<\/em> of the <code>&lt;realm&gt;<\/code> &#8211; all virtual hosts under the engine, a particular host, or a particular web application.<\/p>\n<p>&#8220;Declarative security&#8221; is handled by the server. The server-side programs (servlets, JSPs) do not need any security-aware code. That is, the security control is totally transparent to the server-side programs.<\/p>\n<h4>UserDatabaseRealm<\/h4>\n<p><code>UserDatabaseRealm<\/code> stores user information in a XML file and accessed via JNDI. By default, the XML file is &#8220;<code>$CATALINA_HOME\\conf\\tomcat-users.xml<\/code>&#8220;.<\/p>\n<p>Tomcat provide a JSP example to configure <code>UserDatabaseRealm<\/code> in &#8220;<code>WEB-INF\\examples\\jsp\\security\\protected<\/code>&#8220;, accessed via http:\/\/localhost:8080\/examples\/jsp\/security\/protected\/index.jsp&#8221;. Let us study this example.<\/p>\n<h5>&#8220;<code>conf\\server.xml<\/code>&#8220;<\/h5>\n<p>Tomcat enables <code>UserDatabaseRealm<\/code>, in default installation, with the following configuration directives in &#8220;<code>server.xml<\/code>&#8220;. It defines a JDNI named &#8220;<code>UserDatabase<\/code>&#8221; to the file &#8220;<code>conf\\tomcat-users.xml<\/code>&#8220;. The <code>UserdatabaseRealm<\/code> is defined within the <code>&lt;Engine&gt;<\/code> elements, and thus applicable to all the virtual hosts and web applications, under this server.<\/p>\n<pre>&lt;Server ...... &gt;\r\n  &lt;!-- Global JNDI resources --&gt;\r\n  &lt;GlobalNamingResources&gt;\r\n    &lt;!-- Editable user database that can also be used by\r\n         UserDatabaseRealm to authenticate users --&gt;\r\n    &lt;Resource name=\"<strong>UserDatabase<\/strong>\" auth=\"Container\"\r\n              type=\"org.apache.catalina.<strong>UserDatabase<\/strong>\"\r\n              description=\"User database that can be updated and saved\"\r\n              factory=\"org.apache.catalina.users.MemoryUserDatabaseFactory\"\r\n              pathname=\"<strong>conf\/tomcat-users.xml<\/strong>\" \/&gt;\r\n  &lt;\/GlobalNamingResources&gt;\r\n  \r\n  &lt;Service name=\"Catalina\"&gt;\r\n    &lt;Engine name=\"Catalina\" defaultHost=\"localhost\"&gt;\r\n      &lt;!-- This Realm uses the UserDatabase configured in the global JNDI\r\n           resources under the key \"UserDatabase\".  Any edits\r\n           that are performed against this UserDatabase are immediately\r\n           available for use by the Realm.  --&gt;\r\n      &lt;<strong>Realm<\/strong> className=\"org.apache.catalina.realm.<strong>UserDatabaseRealm<\/strong>\"\r\n             resourceName=\"<strong>UserDatabase<\/strong>\" \/&gt;\r\n      &lt;Host name=\"localhost\" ......\r\n        ......\r\n      &lt;\/Host&gt;\r\n    &lt;\/Engine&gt;\r\n  &lt;\/Service&gt;   \r\n&lt;\/Server&gt;<\/pre>\n<h5>&#8220;<code>conf\\tomcat-users.xml<\/code>&#8220;<\/h5>\n<p>Recall that a user is identified via username\/password. A user is assigned role(s). Accesses for web applications are granted to role(s) instead of individual users. &#8220;<code>Tomcat-users.xml<\/code>&#8221; contains the following roles and username\/password, but <em>commented-out<\/em>. Uncomment them for testing the example.<\/p>\n<pre>&lt;?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?&gt;\r\n&lt;tomcat-users&gt;\r\n  &lt;role rolename=\"tomcat\" \/&gt;\r\n  &lt;role rolename=\"role1\" \/&gt;\r\n  &lt;user username=\"tomcat\" password=\"tomcat\" roles=\"tomcat\" \/&gt;\r\n  &lt;user username=\"both\" password=\"tomcat\" roles=\"tomcat,role1\" \/&gt;\r\n  &lt;user username=\"role1\" password=\"tomcat\" roles=\"role1\" \/&gt;\r\n&lt;\/tomcat-users&gt;\r\n<\/pre>\n<h5>&#8220;<code><em>ContextRoot<\/em>\\WEB-INF\\web.xml<\/code>&#8220;<\/h5>\n<p>For the &#8220;examples&#8221; web context, the security roles are defined using <code> &lt;security-constraint&gt;<\/code> element in &#8220;<code>examples\\WEB-INF\\web.xml<\/code>&#8221; as follows. The URL pattern <code>\/jsp\/security\/protected\/*<\/code> (GET, POST, DELETE, PUT methods) are accessible by users having roles of <code>tomcat<\/code> and <code>role1<\/code> only.<\/p>\n<pre>&lt;web-app ......&gt;\r\n  ......\r\n  &lt;security-constraint&gt;\r\n    &lt;display-name&gt;Example Security Constraint&lt;\/display-name&gt;\r\n    &lt;web-resource-collection&gt;\r\n      &lt;web-resource-name&gt;Protected Area&lt;\/web-resource-name&gt;\r\n      &lt;!-- Define the context-relative URL(s) to be protected --&gt;\r\n      &lt;url-pattern&gt;<strong>\/jsp\/security\/protected\/*<\/strong>&lt;\/url-pattern&gt;\r\n      &lt;!-- If you list http methods, only those methods are protected --&gt;\r\n      &lt;http-method&gt;DELETE&lt;\/http-method&gt;\r\n      &lt;http-method&gt;GET&lt;\/http-method&gt;\r\n      &lt;http-method&gt;POST&lt;\/http-method&gt;\r\n      &lt;http-method&gt;PUT&lt;\/http-method&gt;\r\n    &lt;\/web-resource-collection&gt;\r\n    &lt;auth-constraint&gt;\r\n      &lt;!-- Anyone with one of the listed roles may access this area --&gt;\r\n      &lt;role-name&gt;<strong>tomcat<\/strong>&lt;\/role-name&gt;\r\n      &lt;role-name&gt;<strong>role1<\/strong>&lt;\/role-name&gt;\r\n    &lt;\/auth-constraint&gt;\r\n  &lt;\/security-constraint&gt;\r\n  \r\n  &lt;!-- Default login configuration uses form-based authentication --&gt;\r\n  &lt;login-config&gt;\r\n    &lt;auth-method&gt;<strong>FORM<\/strong>&lt;\/auth-method&gt;\r\n    &lt;realm-name&gt;Example Form-Based Authentication Area&lt;\/realm-name&gt;\r\n    &lt;form-login-config&gt;\r\n      &lt;form-login-page&gt;<strong>\/jsp\/security\/protected\/login.jsp<\/strong>&lt;\/form-login-page&gt;\r\n      &lt;form-error-page&gt;<strong>\/jsp\/security\/protected\/error.jsp<\/strong>&lt;\/form-error-page&gt;\r\n    &lt;\/form-login-config&gt;\r\n  &lt;\/login-config&gt;\r\n        \r\n  &lt;!-- Security roles referenced by this web application --&gt;\r\n  &lt;security-role&gt;\r\n    &lt;role-name&gt;<strong>role1<\/strong>&lt;\/role-name&gt;\r\n  &lt;\/security-role&gt;\r\n  &lt;security-role&gt;\r\n    &lt;role-name&gt;<strong>tomcat<\/strong>&lt;\/role-name&gt;\r\n  &lt;\/security-role&gt;    \r\n<\/pre>\n<h5>Form-based Authentication Method<\/h5>\n<p>The above example uses FORM-based authentication method, defined in element <code>&lt;login-config&gt;<\/code>. All accesses to the protected URL (<code>http:\/\/localhost:8080\/examples\/jsp\/security\/protected\/*<\/code>) will be redirected to the <code>login.jsp<\/code> page (defined in <code>&lt;form-login-page&gt;<\/code>), which prompts user for the credential. For example, if a user requests for <code>http:\/\/localhost:8080\/examples\/jsp\/security\/protected\/index.jsp<\/code>, the <code>login.jsp<\/code> will be displayed.<\/p>\n<p>The <code>login.jsp<\/code> page shall contain a html <code>&lt;form&gt;<\/code> (thus called Form-based authentication):<\/p>\n<pre>&lt;html&gt;\r\n&lt;head&gt;&lt;title&gt;Login Page for Examples&lt;\/title&gt;&lt;\/head&gt;\r\n&lt;body&gt;\r\n&lt;form method=\"POST\" action='&lt;%= response.encodeURL(\"<strong>j_security_check<\/strong>\") %&gt;' &gt;\r\n  Username:&lt;input type=\"<strong>text<\/strong>\" name=\"<strong>j_username<\/strong>\"&gt;\r\n  Password:&lt;input type=\"<strong>password<\/strong>\" name=\"<strong>j_password<\/strong>\"&gt;\r\n  &lt;input type=\"submit\" value=\"Log In\"&gt;\r\n&lt;\/form&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>The login page shall submit the username and password in parameters <code>j_username<\/code> and <code>j_password<\/code> to <code>j_security_check<\/code>. You should use <code>&lt;input type=\"password\" ...&gt;<\/code> for the password text field, which will display the password as *&#8217;s. The <code>response.encodeURL(<em>URL<\/em>)<\/code> encodes the specified URL by including the session ID if URL-rewriting is used for session tracking; it returns the URL unchanged if cookie is used. For robust session tracking, all URLs emitted by server-side programs (servlet\/JSP) should be run through this method.<\/p>\n<p>If login fails, user will be redirected to <code>error.jsp<\/code> page, for example,<\/p>\n<pre>&lt;html&gt;\r\n&lt;head&gt;&lt;title&gt;Error Page For Examples&lt;\/title&gt;&lt;\/head&gt;\r\n&lt;body&gt;\r\nInvalid username and\/or password, please try again\r\n&lt;a href='&lt;%= response.encodeURL(\"index.jsp\") %&gt;'&gt;again&lt;\/a&gt;.\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<p>If login succeeds, the user will get the page he requested for. Study the &#8220;<code>examples\\jsp\\security\\protected\\index.jsp<\/code>&#8221; source.<\/p>\n<ul>\n<li>To logoff, terminate the current session via <code>session.invalidate()<\/code>.<\/li>\n<li>You can use <code>request.getRemoteUser()<\/code> to get the authenticated login username; <code>request.getUserPrincipal()<\/code> to get a <code>java.security.Principal<\/code> object containing the name of the current authenticated user; <code>request.isUserInRole(<em>role<\/em>)<\/code> to check if the authenticated user is included in the specified <em><code>role<\/code><\/em>.<\/li>\n<\/ul>\n<h5>HTTPS<\/h5>\n<p>The username and password send in form data are in clear text, and susceptible to eavesdropping. Hence, it is important to encrypt the transport by turning on SSL (HTTPS). Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/howto\/Tomcat_More.html#tomcatssl\">Tomcat with SSL<\/a>&#8221; on how to setup Tomcat with SSL.<\/p>\n<p>To enforce user to use secure transport (HTTPS), add a <code>&lt;transport-guarantee&gt;CONFIDENTIAL&lt;\/transport-guarantee&gt;<\/code>, inside the <code>&lt;security-constraint&gt;<\/code>, as follows:<\/p>\n<pre>&lt;security-constraint&gt;\r\n  &lt;display-name&gt;Example Security Constraint&lt;\/display-name&gt;\r\n  &lt;web-resource-collection&gt;\r\n    &lt;web-resource-name&gt;Protected Area&lt;\/web-resource-name&gt;\r\n    &lt;url-pattern&gt;\/jsp\/security\/protected\/*&lt;\/url-pattern&gt;\r\n    ......\r\n  &lt;\/web-resource-collection&gt;\r\n  &lt;auth-constraint&gt;\r\n    &lt;role-name&gt;tomcat&lt;\/role-name&gt;\r\n    ......\r\n  &lt;\/auth-constraint&gt;\r\n  &lt;!-- must use SSL for secure transport --&gt;\r\n  <strong>&lt;user-data-constraint&gt; &lt;transport-guarantee&gt;CONFIDENTIAL&lt;\/transport-guarantee&gt; &lt;\/user-data-constraint&gt;<\/strong>\r\n&lt;\/security-constraint&gt;<\/pre>\n<p>All accesses to http at port 8080 (e.g., http:\/\/localhost:8080\/examples\/jsp\/security\/protected\/index.jsp) will be redirected to https at port 8443 (e.g., https:\/\/localhost:8443\/examples\/jsp\/security\/protected\/index.jsp).<\/p>\n<h5>HTTP Basic Authentication<\/h5>\n<p>Other than Form-based authentication, you could use the <em>Basic Authentication Scheme<\/em> available in HTTP server to authenticate user. Change the <code>&lt;login-config&gt;<\/code>&#8216;s <code>&lt;auth-method&gt;<\/code> to <code>BASIC<\/code>, instead of <code>FORM<\/code>.<\/p>\n<pre>&lt;login-config&gt;\r\n   <strong>&lt;auth-method&gt;BASIC&lt;\/auth-method&gt;<\/strong>\r\n   &lt;realm-name&gt;Example Basic Authentication Area&lt;\/realm-name&gt;\r\n&lt;\/login-config&gt;<\/pre>\n<p>Again, Basic Authentication sends the username and password in clear text. It is totally insecure, unless you should use a secure transport (HTTPS).<\/p>\n<h5>HTTP Digest Authentication<\/h5>\n<p>Tomcat also support HTTP <em>Digest Authentication Scheme<\/em> to authenticate user. Change the <code>&lt;login-config&gt;<\/code>&#8216;s <code>&lt;auth-method&gt;<\/code> to <code>DIGEST<\/code>. Instead of sending password in clear text, the <em>digest<\/em> of password is send to the server. Digest authentication is more secure.<\/p>\n<pre>&lt;login-config&gt;\r\n   <strong>&lt;auth-method&gt;BASIC&lt;\/auth-method&gt;<\/strong>\r\n   &lt;realm-name&gt;Example Basic Authentication Area&lt;\/realm-name&gt;\r\n&lt;\/login-config&gt;<\/pre>\n<h4>JDBCRealm<\/h4>\n<p>In <code>JDBCRealm<\/code>, user information kept in a relational database such as MySQL, accessed via JDBC.<\/p>\n<h5>Setting up Database<\/h5>\n<p>We shall set up our user database in MySQL. Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/sql\/MySQL_HowTo.html\">How to install MySQL<\/a>&#8220;.<\/p>\n<p>The following script can be used to set up the user database. Two tables are required: a <code>users<\/code> table containing username and password, and a <code>user_roles<\/code> containing username and the role assigned.<\/p>\n<pre>create database tomcat_users;\r\n  \r\nuse tomcat_users;\r\n  \r\ncreate table users (\r\n  username varchar(15) not null primary key,\r\n  password varchar(15) not null\r\n);\r\n  \r\ncreate table user_roles (\r\n  username varchar(15) not null,\r\n  role     varchar(15) not null,\r\n  primary key (username, role)\r\n);\r\n  \r\ninsert into users values \r\n  ('tomcat', 'tomcat'), \r\n  ('both', 'tomcat'), \r\n  ('role1', 'tomcat');\r\n  \r\ninsert into user_roles values \r\n  ('tomcat', 'tomcat'), \r\n  ('role1', 'role1'), \r\n  ('both', 'tomcat'), \r\n  ('both', 'role1');<\/pre>\n<h5>JDBC Driver<\/h5>\n<p>Next, copy the MySQL&#8217;s JDBC driver (&#8220;<code>mysql-connector-java-5.1.xx-bin.jar<\/code>&#8220;) into Tomcat&#8217;s lib (&#8220;<code>$CATALINA_HOME\\lib<\/code>&#8220;).<\/p>\n<h5>&#8220;<code>conf\\server.xml<\/code>&#8220;<\/h5>\n<pre>&lt;Realm className=\"org.apache.catalina.realm.<strong>JDBCRealm<\/strong>\" debug=\"99\"\r\n   driverName=\"com.mysql.jdbc.Driver\"\r\n   connectionURL=\"jdbc:mysql:\/\/localhost\/<strong>tomcat_users<\/strong>?user=dbuser&amp;amp;password=dbpass\"\r\n   userTable=\"users\" userNameCol=\"username\" userCredCol=\"password\"\r\n   userRoleTable=\"user_roles\" roleNameCol=\"role\" \/&gt;\r\n<\/pre>\n<h5>&#8220;<em><code>ContextRoot<\/code><\/em><code>\\WEB-INF\\web.xml<\/code>&#8220;<\/h5>\n<p>Same as <code>UserDatabaseRealm<\/code>.<\/p>\n<h5>Authentication Methods<\/h5>\n<p>Same as <code>UserDatabaseRealm<\/code>, you can use <code>FORM<\/code>, <code>BASIC<\/code> or <code>DIGEST<\/code> authentication method.<\/p>\n<h5>Testing<\/h5>\n<p>You need to start MySQL server before starting the Tomcat Server.<\/p>\n<h3>Setting up Database Connection Pooling in Tomcat<\/h3>\n<p>Read &#8220;<a href=\"http:\/\/www3.ntu.edu.sg\/home\/ehchua\/programming\/java\/JavaWebDBApp.html#TomcatDBCP\">Database Connection Pooling in Tomcat with MySQL<\/a>&#8220;.<\/p>\n<h3>Configuring Virtual Hosts<\/h3>\n<p>To set up a virtual host called &#8220;www.mytest.com&#8221; (suppose that you have registered this hostname with at static IP address). Include the following <code>&lt;Host&gt;<\/code> element in <code>server.xml<\/code> under the <code>Engine Catalina<\/code>:<\/p>\n<pre>&lt;Engine name=\"Catalina\" &gt;\r\n  &lt;Host name=\"localhost .....&gt;\r\n    ......\r\n  &lt;\/Host&gt;\r\n  <strong>&lt;Host name=\"www.mytest.com\" appBase=\"webapps_mytest.com\" unpackWARs=\"true\" autoDeploy=\"true\" &gt; &lt;Alias&gt;mytest.com&lt;\/Alias&gt; &lt;Valve className=\"org.apache.catalina.valves.AccessLogValve\" directory=\"logs\" prefix=\"mytest.com_access_log.\" suffix=\".log\" pattern=\"%h %l %u %t &amp;quot;%r&amp;quot; %s %b\" resolveHosts=\"false\" \/&gt; &lt;\/Host&gt;<\/strong>\r\n&lt;\/Engine&gt;<\/pre>\n<p>The above lines configure a virtual host with hostname &#8220;<code>www.mytest.com<\/code>&#8220;, with webapps base directory at &#8220;<code>$CATALINA_HOME\\webapps_mytest.com<\/code>&#8220;. We also define a alias called &#8220;<code>mytest.com<\/code>&#8220;. That is, this host can be accessed via <code>http:\/\/www.mytest.com:port<\/code> or <code>http:\/\/mytest.com:port<\/code>. We also define a <code>Valve<\/code>, which intercepts the request message to write a log entries (similar to <code>localhost<\/code>).<\/p>\n<p>Next:<\/p>\n<ol>\n<li>Create a directory &#8220;<code>webapps_mytest.com<\/code>&#8221; under <code>$CATALINA_HOME<\/code>, according to the <code>appBase<\/code>.<\/li>\n<li>Create a web application called <code>ROOT<\/code>, by creating a directory <code>ROOT<\/code> under the &#8220;<code>webapps_mytest.com<\/code>&#8220;. Recall that <code>ROOT<\/code> was configured with an empty string URL. In other words, <code>http:\/\/www.mytest.com:port\/<\/code> accesses the <code>ROOT<\/code> application.<\/li>\n<li>Create a directory &#8220;<code>www.mytest.com<\/code>&#8221; under &#8220;<code>conf\\Catalina<\/code>&#8220;.<\/li>\n<li>Write a welcome page called &#8220;<code>index.html<\/code>&#8221; and save it in &#8220;<code>webapps_mytest.com\\ROOT<\/code>&#8220;.\n<pre>&lt;html&gt;\r\n&lt;head&gt;&lt;title&gt;Testing Virtual Host&lt;\/title&gt;&lt;\/head&gt;\r\n&lt;body&gt;\r\n  &lt;h1&gt;<strong>It's work on virtual host<\/strong>&lt;\/h1&gt;\r\n&lt;\/body&gt;\r\n&lt;\/html&gt;<\/pre>\n<\/li>\n<\/ol>\n<p>To test the virtual host, without registering the hostname with an ISP, edit &#8220;<code>C:\\Windows\\System32\\drivers\\etc\\hosts<\/code>&#8221; to include the following lines (required administrative authority):<\/p>\n<pre>127.0.0.1   www.mytest.com\r\n127.0.0.1   mytest.com<\/pre>\n<p>These lines maps host names <code>www.mytest.com<\/code> and <code>mytest.com<\/code> to IP address 127.0.0.1, which is the localhost. As the IP software checks the <code>host<\/code> file before asking Domain Name Service (DNS) to resolve a host name, you willl be able to test your virtual host.<\/p>\n<p>Now, you are ready to test the virtual hosts. Start the Tomcat server and issue these URL:<\/p>\n<pre>http:\/\/www.mytest.com:8080\r\nhttp:\/\/mytest.com:8080\r\nhttp:\/\/www.mytest.com:8080\/\r\nhttp:\/\/mytest.com:8080\/\r\nhttp:\/\/www.mytest.com:8080\/index.html\r\nhttp:\/\/mytest.com:8080\/index.html<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<h4>REFERENCES &amp; RESOURCES<\/h4>\n<ul>\n<li>Tomcat mother site @ <a href=\"http:\/\/tomcat.apache.org\/\">http:\/\/tomcat.apache.org<\/a><\/li>\n<li>Tomcat&#8217;s Documentation @ &#8220;<code>$CATALINA_HOME\\webapps\\docs<\/code>&#8220;.<\/li>\n<li>Java Servlet, JavaServer Pages (JSP), and JavaServer Faces (JSF) specifications.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>TABLE OF CONTENTS (HIDE) <\/p>\n<p>1. Introduction1.1 Web Application (Webapp)1.2 Hypertext Transfer Protocol (HTTP)1.3 Apache Tomcat HTTP Server2. How to Install Tomcat 7 and Get Started with Java Servlet Programming2.1 STEP 0: Read the Tomcat Documentation2.2 STEP 1: Download and Install Tomcat2.3 STEP 2: Create an Environment Variable JAVA_HOME2.4 STEP 3: Configure Tomcat Server2.5 STEP 4: [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/1488"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1488"}],"version-history":[{"count":5,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/1488\/revisions"}],"predecessor-version":[{"id":1494,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/1488\/revisions\/1494"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}