top of page

Simple Java Servlet Microservice

Nowadays most of the micro services we develop are in spring boot. Sometimes we need to convert an old application written in Java to a micro service. Sometimes there are existing servlet based applications running as a cloud based application or micro service which have not been converted and need to be maintained. We need to know what a servlet-based web application looks like. In this blog post we will see a minimalistic servlet based web application that can be bundled to be deployed as a micro service.

 

Contents


 

Project Structure

After we create a maven project the project structure will look like as shown below. Here I am using IntelliJ IDE but you can use any IDE of your choice.

The code

The pom.xml

Two things to note here, one is we are using the servlet-api and the second is we need to package the application as a war file, we will use the maven-war-plugin to bundle the application and war needs to be mentioned under the packaging attribute. The war file name will be ROOT.war

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.dibyo.servlet</groupId>
    <artifactId>TestServlet</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.19</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>

        <finalName>ROOT</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <warName>ROOT</warName>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <maven.compiler.source>12</maven.compiler.source>
        <maven.compiler.target>12</maven.compiler.target>
    </properties>
</project>

The about.jsp

The about.jsp is a small jsp page which just has a static html content. When the root url is requested the servlet based web application will return this jsp page by default.

<!DOCTYPE html>
<html>
<head><title>my-servlet</title></head>
<body><H1>My Servlet</H1></body>
</html>

The web.xml

In the web.xml we need to provide the servlet definition in a xml based declarative form. We need to give an unique name within the application for each servlet using the <servlet-name> tag then we need to specify which class in our code this servlet points to, using the <servlet-class> tag. This definition of the servlet goes under the <servlet> parent tag. After that, in the <servlet-mapping> we map the servlet name with the URL the servlet will serve. This means after the base URL when this particular path is used to send a HTTP(S) request the request is sent to this class to handle the request. We need to note that the class may not be able to handle the request. For example, if we have not implemented a handler to handle POST methods in the class but we send a post request the servlet class will not be able to handle the request. In that case a standard error specifying that the method is not supported by this servlet is shown to the requester.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <display-name>my-servlet<display-name>

    <servlet>
        <display-name>MyServlet</display-name>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>com.dibyo.servlet.MyServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/v1/hello/*</url-pattern>
    </servlet-mapping>
</web-app>

We can also enhance the web.xml with several features. For example, we can restrict certain paths with an authentication mechanism and many more.


The Servlet class MyServlet.java

We need to extend the HttpServlet class and we need to override the init() method. Here we can write logics that need to be run at the web application initialize, when the application is deployed. We can also configure the servlet using the ServletConfig interface. Javatpoint has a good example on usage of ServletConfig. Javatpoint also has a detailed list of the different methods we need to implement in HttpServlet. Here is an example class that serves the HTTP GET and POST requests. To serve GET requests the doGet() method needs to be implemented and the doPost() method needs to be implemented to serve POST requests. In this example code both requests reply with a string “Hello!” with HTTP status code 200.

package com.dibyo.servlet;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyServlet extends HttpServlet {
    private static final String utf8 = "UTF-8";
    private static final String CONTENT_TYPE = "application/json";
    private static final int bufferSize = 1024 * 32;

    private final Logger logger = LoggerFactory.getLogger(MyServlet.class);

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }
    protected void doPost(HttpServletRequest req,HttpServletResponse res) {
        reply(res);
    }
    protected void doGet(HttpServletRequest req,HttpServletResponse res) {
        reply(res);
    }

    private void reply(HttpServletResponse response) {
        response.setBufferSize(bufferSize);
        //response.getSession(true);
        logger.info("Request received...");

        response.setStatus(200);
        response.setContentType(CONTENT_TYPE);
        response.setCharacterEncoding(utf8);

        try{
            PrintWriter writer = response.getWriter();
            writer.write("Hello!");
            writer.flush();
        } catch(OutOfMemoryError e) {
            logger.error(e.getMessage(), e);
            response.setStatus(500);
        } catch(Throwable t) {
            logger.error(t.getMessage(), t);
            response.setStatus(500);
        }
    }
}

Creating An War

We need to go to the root directory and execute the maven command

<path>/single-module > mvn clean install

It will build a war named ROOT.war under a sub folder named target.


How to run

To run the web application locally we can install tomcat. The tomcat documentation explains how we can install tomcat. After installing tomcat we need to put the ROOT.war in the tomcat server under webapps sub folder and start the tomcat server.


Interacting with the Web Application

We can request for the about.jsp page using the localhost and port. generally the default port for tomcat is 8080 but can be different if you have any other application running in the same port.

Calling the http://localhost:8080/about.jsp returns the below output as an html page.

            Hello from My Servlet

Calling the specific url endpoint http://localhost:8080/v1/hello/1 returns below output

            Hello!

Today, we have learned what we need to run a minimal servlet based micro service.


718 views0 comments

Recent Posts

See All
bottom of page