Setting up a Minimal Java Servlet Application


Published: 2017-11-05
Updated: 2018-12-26
Web: https://fritzthecat-blog.blogspot.com/2017/11/setting-up-minimal-java-servlet.html


There is an HTML element named FORM that provides interactivity with the web-server the page comes from, without having to use JavaScript and AJAX. As soon as you use that element, you will want to have access to the web-server the page was loaded from, to see what was sent to the server on submit, and maybe program what should be the response. This is the world of the HTTP protocol. Using the FORM element you move from a web page to a web application.

This Blog is about setting up a minimal web server. Intent is to see what the browser-client FORM sends, and maybe to provide a response. I will use the the platform-independent language Java, the Java project-management tool Maven, the Java web server Jetty, and the Java servlet specification to do that.

Creating a Webapp Skeleton via Maven

After installing Java and Maven, open a command input window and enter


mvn -version

to test it. When it is not available, you may need to put $MAVEN_HOME/bin into your operating system path, where $MAVEN_HOME is the directory you unpacked Maven into.

Now change to a directory where your servlet project can reside, and enter following Maven command line:


cd my-projects

mvn archetype:generate \
-DarchetypeArtifactId=maven-archetype-webapp \
-DgroupId=my.web.examples \
-DartifactId=simplewebapp \
-DinteractiveMode=false

This will generate a directory simplewebapp in current directory, and create files and directories below it that represent the server-side of a web-application, managed by Maven. Any Java IDE like Eclipse, NetBeans or Idea should be able to support such a directory structure.

The groupId and artifactId are part of the Maven "coordinates", you will find them again inside the generated pom.xml file. The version will be set to 1.0-SNAPSHOT by default. When not having interactiveMode=false, Maven will prompt you to input configurations.

Maven chooses the artifactId (simplewebapp) to be the name of the directory it creates for the application.

simplewebapp
pom.xml
src
main
resources
webapp
index.jsp
WEB-INF
web.xml

Herein are only three files:

  1. The pom.xml file is the Maven project maintenance file.

    <project
    xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>my.web.examples</groupId>
    <artifactId>simplewebapp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <dependencies>
    </dependencies>

    <build>
    <finalName>simplewebapp</finalName>
    </build>

    </project>

    Mind that I removed the now unneeded dependency to JUnit (Java test framework), and some other unneeded elements.

  2. The index.jsp file is what you will see when the servlet is running that we are about to build. The extension ".jsp" refers to Java Server Pages, one of the oldest web application frameworks. A JSP file is a mix of HTML and JSP tags, so you always can put HTML into it.

    <html>
    <body>
    <h2>Hello World!</h2>
    </body>
    </html>
  3. The web.xml file finally is the servlet deployment descriptor. There can be several servlets. When you drop a packed .war file ("web archive", containing a web.xml) into the the deployment-directory of a servlet container, it will load the web-app from the archive using WEB-INF/web.xml.

    <!DOCTYPE web-app PUBLIC
    "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd" >

    <web-app>
    <display-name>Archetype Created Web Application</display-name>
    </web-app>

Running the Web App

Before we can test the application, we need to tell Maven to download Jetty. This is a lightweight HTTP-server for development and test, not suited for production.

In the <build> section of the Maven pom.xml, add the Jetty plugin:

  <build>
<finalName>simplewebapp</finalName>
<!-- This would produce a simplewebapp.war on "mvn package" -->

<plugins>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>9.4.7.v20170914</version>
<configuration>
<scanIntervalSeconds>2</scanIntervalSeconds>
<webApp>
<contextPath>/simplewebapp</contextPath>
</webApp>
<httpConnector>
<port>8080</port>
</httpConnector>
</configuration>
</plugin>

</plugins>

</build>

Mind that we need to configure the web-application's context-path ("/simplewebapp"). The plugin will listen on port 8080 for HTTP requests. The port element is not required, as 8080 is the org.eclipse.jetty default port.

Now Maven is ready to run the web application. There is no servlet yet inside, but we should see index.jsp.

Change into the directory simplewebapp and run following Maven command line.


cd simplewebapp
mvn run:jetty

In case Maven tells you "[INFO] Started Jetty server", try to enter this URL into the address line of a new browser tab:

You should see this output from index.jsp:

You can shutdown the running Jetty server by typing Ctl-C on the command window.

Adding a Servlet

Before we can add a servlet, we need to tell Maven the dependency to the servlet-specification. Inside the <dependencies> section in pom.xml, add following lines:

  <dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

Now create following new directories, and add the SimpleServlet.java source file.

simplewebapp
src
main
java
my
web
examples
SimpleServlet.java

Put following content into it. It is a servlet by extending HttpServlet, which comes with the added servlet dependency.

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package my.web.examples;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class SimpleServlet extends HttpServlet
{
private int requestNumber;

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
printRequest("doGet", request, response);
}

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
printRequest("doPost", request, response);
}

private void printRequest(String httpMethodName, HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
requestNumber++;
String page =
"<!DOCTYPE html><html><body>\n"+
"<p>SimpleServlet "+httpMethodName+
"(), request "+requestNumber+
" is:</p>\n<pre>"+request+
"</pre>\n</body></html>";
PrintWriter out = response.getWriter();
out.println(page);
out.flush();
out.close();
}
}

Now edit web.xml and configure the Java source as a servlet-class.

<web-app>
<display-name>My Simple Servlet</display-name>

<servlet>
<servlet-name>uniqueServletName</servlet-name>
<servlet-class>
my.web.examples.SimpleServlet
</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>uniqueServletName</servlet-name>
<url-pattern>/simple-servlet</url-pattern>
</servlet-mapping>

</web-app>

In the command window, start Jetty again by typing


mvn run:jetty

Enter this URL into the address line of a new browser tab (no trailing slash!):

You should see this:

You could remove index.jsp now if you want. The servlet does not depend on it.

Summary

Having a servlet running, we can let it display a HTML form element, and watch what is coming back when we submit that form. But to debug the servlet, we would need to attach an IDE to simplewebapp. May be subject to further Blog articles.

Mind that servlets are a very low level of web programming. You would end up in a complex mixture of HTML, Java, CSS and JavaScript. Prefer JSP, or any other framework like JSF.





ɔ⃝ Fritz Ritzberger, 2017-11-05