The guide continues to give a step-by-step introduction to using Tomcat and changing its behaviour to suit your needs through the use of custom servlets. This information is IDE-agnostic. Note that the hotkeys are IntelliJ hotkeys.
This guide begins by providing a step-by-step introduction for how to set-up your own local instance of a Tomcat server using IntelliJ Ultimate Edition 2016.1 as your IDE.
At the end of this document you will be able to receive query
parameters through the URL address bar (in other words an HTTP GET
request) in your browser, i.e. given the URL
http://localhost:8080/banana?answer=42
you will be able to retrieve the answer parameter and its
value and getting access to the entire URI (including the banana text).
Lastly we will accept user-input through standard HTML input
fields which is sent to us through the HTTP POST request method
and echo it back to the end-user.
For reference you will find the source code created at the end of the project in the TomcatExample directory.
Note: This guide makes heavy use of images, and you may have a different theme set for your IntelliJ installation. If you like this color scheme it is called Dracula and is available by default.
Note: In production you should sanitize HTML and user-input using a third-party library such as the OWASP Java HTML sanitizer. We will skip this pre-requisite and roll our own sanitizer in this guide to save you the up-front time investment.
Acquiring the IDE is outside the scope of this tutorial, note that you will require the Ultimate Edition to use Tomcat as the Community Edition does not have support for JavaEE. Ultimate Edition is free for students. You can use your University Email Address to apply for free Jetbrains products (IntelliJ is a Jetbrains product) or with an ISIC/ITIC membership
You will require the Java 8 JDK, this guide has only been tested on two Linux distributions, specifically Debian and Ubuntu. Installation instructions for the Java 8 JDK is omitted here.
You will require Apache Tomcat 8.0.x which is, at the time of writing (2016-04-25) the latest stable version of Tomcat. It works with Java 7 SE and later versions of Java.
Installing Tomcat requires sudo privileges!
- Install Java JDK 8.
- Download the Core Tomcat 8.0.33
tar.gzfile and decompress it. (pgp, md5, sha1). - Create a new directory
/opt/tomcat, this requiressudoprivileges! - Move the files from step 2 to the directory
/opt/tomcat. This operation also requiressudo. - In your shell perform the following commands: (ensure that
JAVA_HOMEis set properly first)export CATALINA_HOME=/opt/tomcat - Start Tomcat by inputting
/opt/tomcat/bin/startup.shin your terminal. - Use your web browser to check that Tomcat is running by visiting localhost:8080.
Clean up by killing Tomcat,
./opt/tomcat/bin/shutdown.sh
Start by creating a new project in IntelliJ,
When creating the project it is important to create a Spring Project (we won't actually use any Spring features) that is a web application using a custom application server.
We click the "New..." button and then select the "Tomcat Server" option
If you've followed the instructions as is up to this point you can input the path shown in the following image, otherwise specify the absolute path to your Tomcat Home directory.
We proceed by choosing our Project name and location. You may choose any setting here and whenever you see "TomcatExample" in the subsequent steps simply change it to reflect your chosen project name.
IntelliJ generates some project boiler plate. If you cannot see the project browser immediately (i.e. the directory tree) simply click the TomcatExample button which is far up to your left (look at the top of the below image)
You can now run your Tomcat application straight out of the box by
finding the "Run" menu at the top of your IntelliJ window or using the shortcut Shift+F10. Input
http://localhost:8080/ in your web-browser
and you will be presented with an empty page and the word$END$.
For this step leave Tomcat running in IntelliJ, do not close the process.
In your index.jsp file (available in the web directory) and replace
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Tomcat-logo.svg/2000px-Tomcat-logo.svg.png?raw=true">
to use Tomcat to present an image of a Tomcat (meta).
Now use the short-cut Ctrl+F10 to open the Update dialogue. Select
the "Update resources" option and refresh your web-browser localhost
session.
In this section we will create our own servlet to replace the default servlet provided by Tomcat. Essentially this boils down to extending the proper classes and configuring our web application through its configuration files.
Start by creating a package in your src directory. This is
required as servlets have to be kept in a named package for
deployment, instead of the default "no-name" package. In this guide, we
will name our package example, and create a class MyHttpServlet.
First we write a naive, inflexible and illegible servlet (we will decouple the HTML from the servlet soon),
package example;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyHttpServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// Set the response message's MIME type.
response.setContentType("text/html;charset=UTF-8");
// Write the response message, in an HTML document.
try (PrintWriter out = response.getWriter()) {
out.println("<!DOCTYPE html>"); // HTML 5
out.println("<html><head>");
out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
out.println("<title>TomcatExample</title></head>");
out.println("<body>");
out.println("<h1 style=\"font-size: 4em;\">Hello, World!</h1>");
out.println("</body></html>");
}
}
}To use our servlet we have to add a deployment descriptor to our web.xml file
which is inside the web/WEB-INF/ folder,
web
|
+-- index.jsp
|
+-- WEB-INF
|
+-- web.xml
We insert the following inside the <web-app> scope,
<servlet>
<servlet-name>TomcatHelloWorldExample</servlet-name>
<servlet-class>example.MyHttpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TomcatHelloWorldExample</servlet-name>
<url-pattern>/tomcat_example</url-pattern>
</servlet-mapping>
The important part is the <servlet> and <servlet-mapping>
elements.
The element <servlet> connects a Java Servlet class
(example.MyHttpServlet) to the servlet named
MyHttpServlet. Then the element <servlet-mapping> maps the servlet
MyHttpServlet to the URL pattern /tomcat_example.
Combined together, the two elements essentially say that requests to
this web application at the URL /tomcat_example should be handled by the class
example.MyHttpServlet.
Now we re-run our application (close it and start it again, or `Ctrl+F5) and navigate to http://localhost:8080/tomcat_example.
Notice the extension after the port specifier. It is the
same as the url-pattern we defined in the servlet-mapping closure,
hence we are sending a request to the web application which is then
handled by the MyHttpServlet.
We want to separate the behaviour of our servlet, which should tend to
business logic, which in the context of this application means retrieving the
appropriate data in response to the user query from the end-user
presentation, i.e. we do not want to pester our source with a
PrintWriter.
Conceptually we want our website to be composed in two distinct layers the "business logic layer" which is handled by our Java Servlets and a "presentation" layer, which we will handle with JSP.
We do this by imbuing the HttpServletRequest object with relevant
data before deferring the request to a JSP page, which is essentially
a HTML document with template capabilities.
Begin by overriding the doGet method inside the MyHttpServlet class,
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("title", "TomcatExample");
request.setAttribute("foo", "Sterm trepers!");
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
We set two arbitrary attributes. The foo attribute is meant to
demonstrate that there is not a set of allowed attributes, you may
define these on your own. The first argument is the name of the
attribute, the key, and the second argument is its value.
We then forward the request through to the index.jsp file which
we have updated to contain:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title><%= request.getAttribute("title") %></title>
</head>
<body>
<h1 style="font-size: 4em;">Ermahgerd, <%= request.getAttribute("foo") %></h1>
</body>
</html>
Re-run your Tomcat application (as we changed the servlet we cannot simply update the resources live as we must update the classes as well) and notice how the tab title in your browser is "TomcatExample" and that the page renders "Ermahgerd, Sterm trepers!" above the Tomcat image.
We will now proceed to accept a query parameter in the URL address
bar, specifically ?bar=.
We then update our index.jsp by discarding the image (its just noise
at this point) and call the getParameter method on the request
object.
<%-- index.jsp --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title><%= request.getAttribute("title") %></title>
</head>
<body>
<h1 style="font-size: 4em;">Ermahgerd, <%= request.getAttribute("foo") %></h1>
<h1 style="font-size: 4em;"><%= request.getParameter("bar") %></h1>
</body>
</html>
Re-run your Tomcat application and visit http://localhost:8080/tomcat_example/?bar=42 and observe how your page renders "42".
If you instead visit http://localhost:8080/tomcat_example/ you get "null" as there is no value set for the parameter.
In this next section we will update our application to accept additional URI information. This is important when accessing specific resources and it will also allow us to showcase how to import Java methods into our JSP file.
In the doGet method of the servlet replace the call to the forward method with
the include method,
request.getRequestDispatcher("/index.jsp").include(request, response);
We then proceed by updating the <url-pattern> inside the web.xml
file to <url-pattern>/tomcat_example/*</url-pattern>. The * is a
wildcard character so we will accept any text after the
/tomcat_example servlet specifier. That is, it matches all sub-paths
under /tomcat_example.
Notice that we did not have to do this to accept query parameters in the earlier step . In this step we will want to sanitize the user-input. As stated earlier you should use a third-party library for doing this but we will hand-roll our own to be brief.
Create the following class (disregard the implementation is not important):
// You can create the class in any package.
// It does not have to be inside the same package
// as the servlet.
package example;
public class HtmlSanitizer {
public static String sanitize(String unsafeString) {
if (unsafeString == null) return null;
int len = unsafeString.length();
StringBuilder result = new StringBuilder(len + 20);
char aChar;
for (int i = 0; i < len; ++i) {
aChar = unsafeString.charAt(i);
switch (aChar) {
case '<': result.append("<"); break;
case '>': result.append(">"); break;
case '&': result.append("&"); break;
case '"': result.append("""); break;
default: result.append(aChar);
}
}
return (result.toString());
}
}To access the sanitize method inside our JSP document
we update index.jsp with an import statement,
<%@ page import="example.HtmlSanitizer" %>
and call the method on the relevant string
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="example.HtmlSanitizer" %>
<html>
<head>
<title><%= request.getAttribute("title") %></title>
</head>
<body>
<h1 style="font-size: 4em;">Ermahgerd, <%= request.getAttribute("foo") %></h1>
<h1 style="font-size: 4em;"><%= request.getParameter("bar") %></h1>
<!-- The sanitize method is called on the line below -->
<h1 style="font-size: 4em;"><%= HtmlSanitizer.sanitize(request.getRequestURI()) %></h1>
</body>
</html>
and re-run your application, this time visit http://localhost:8080/tomcat_example/apa?bar=2
Your page should now look like this:
We end this guide by accepting user input provided on the web-page.
We add an additional method in our servlet that does the exact same
thing as the doPost method.
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}And update your index.jsp to:
<%-- index.jsp --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="example.HtmlSanitizer" %>
<html>
<head>
<title><%= request.getAttribute("title") %></title>
</head>
<body>
<h1 style="font-size: 4em;">Ermahgerd, <%= request.getAttribute("foo") %></h1>
<h1 style="font-size: 4em;"><%= request.getParameter("bar") %></h1>
<h1 style="font-size: 4em;"><%= HtmlSanitizer.sanitize(request.getRequestURI()) %></h1>
<form method='get'>
Firstname: <input type='text' name='firstname'><br />
Lastname: <input type='text' name='lastname'><br />
<input type='submit' value='SEND'>
</form>
<h1 style="font-size: 4em;">Firstname: <%= HtmlSanitizer.sanitize(request.getParameter("firstname")) %></h1>
<h1 style="font-size: 4em;">Lastname: <%= HtmlSanitizer.sanitize(request.getParameter("lastname")) %></h1>
</body>
</html>
You can now visit localhost:8080/ or localhost:8080/tomcat_example/apa/some-stuff?bar=other-stuff and enter values into the form, post the data through the send button and watch the page update.
The following two figures shows the page localhost:8080/tomcat_example/some-stuff?bar=other-stuff before ) and after the form has been posted.
This concludes the guide, remember that this is just to get you started with Tomcat. Next on your agenda is using React.js+Ajax+JSON as opposed to JSP files to serve dynamic content.








