Simple Servlet Program in Java

Simple Servlet Program in Java | In the previous tutorials, we learned about web application, servlet container, servlet, what is tomcat and how to install tomcat server, tomcat installation directory structure. Now it’s time to develop a simple servlet program. To develop a servlet program you must have knowledge about important classes and methods of Servlet API. Learn it here:- Servlet in Java – Introduction

Table Of Contents


Develop Servlet Web Application in Java

Description:- After requesting the servlet component from the browser we should get a welcome message, current data, and time. 

Required Software to Develop Java Servlet Program,

Let us see the procedure to develop a Java web application having servlet components as the dynamic web component. To learn the basics of servlet we will develop this example manually without using any IDE, after a few examples we will use Eclipse IDE to develop Servlet-based web applications.

Create Deployment Directory Structure

Step1) Create deployment directory or staging directory structure for Java web application.

In the servlet introduction topic, we have already learned about the deployment directory structure of a Java web application. Based on that knowledge, create a deployment directory structure. In this Java servlet program, we won’t take any static resource (HTML file, image, and e.t.c.).

DateApp
   |=> WEB-INF
      |=> web.xml
      |=> classes
          |=> DateServlet.java

Develop Servlet Component

Step2) Develop the servlet component DateServlet.java

package com.kp.servlet;

import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;
import java.util.*;

public class DateServlet extends HttpServlet {
   public void service(HttpServletRequest req, HttpServletResponse res) 
      throws ServletException, IOException {

      // set response content type
      res.setContentType("text/html");

      // get PrintWriter 
      PrintWriter pw = res.getWriter();

      // business logic 
      Date d = new Date();
      // write output message to response object
      // using PrintWriter obj
      pw.println("<h1>Welcome to Servlet</h1>");
      pw.println("<h2>Date and time::"+ d.toString() +"</h2>");

      // close stream
      pw.close();
   }
}

The servlet container accepts the .class not the .java file therefore we must compile it and create the .class file. 

Step3) Add <Tomcat_home>\lib\servlet-api.jar file to the classpath.

The above DateServlet.java contains code that belongs to servlet API, not the JDK API. And if we are writing any code which doesn’t belong to JDK API then those related jar files must be added to the classpath. Then only we can compile those programs. Therefore we have to add the servlet-api.jar file to the classpath. See:- What is classpath and different ways to add a classpath 

My PC => Properties => Advanced System Settings => Environment Variables,

Variable Name: CLASSPATH
Variable Value: D:\Installed\Web Servers\Tomcat10\lib\servlet-api.jar;.

Apply the changes and click on ok. We need to add servlet-api.jar to classpath only for once not every time while developing servlet components.

Step4) Compile Servlet component DateServlet.java

Generate the .class file in packages. To compile open cmd from the current working directory where DateServlet.java is available,

javac -d . DateServlet.java

Don’t forgot to add the dot (.) while compiling the java file, it will create the package in the current folder. After compilation, we get the following file structure in the classes folder,

|=> classes
   |=> DateServlet.java
   |=> com 
      |=> kp
         |=> servlet
            |=> DateServlet.class

Develop Servlet Configuration File

Step5) Develop deployment descriptor i.e. web.xml file.

Develop web.xml file to configure servlet component and to map servlet component with URL. Note that XML is case-sensitive and strictly typed.

<web-app>
   <!--Servlet Configuration-->
   <servlet>
      <servlet-name>date</servlet-name>
      <servlet-class>com.kp.servlet.DateServlet</servlet-class>
   </servlet>

   <!--Servlet Mapping -->
   <servlet-mapping>
      <servlet-name>date</servlet-name>
      <url-pattern>/home</url-pattern>
   </servlet-mapping>
</web-app>

Now our Java servlet example or web application is ready and we can test it.

Test the Servlet Web Application

Step6) Deploy the web application.
Copy the developed Java servlet web application to <Tomcat_home>\webapps folder.

Step7) Start tomcat server.
To start tomcat server double click on <Tomcat_home>\bin\Tomcat10.exe

Step8) Test the web application in the browser address bar.

Type http://localhost:8080/DateApp/home in the browser or click on that hyperlink. If everything was done properly then we will get a welcome message, current date, and time. 

When we give another request (refresh or F5) then we can see the updated current time. Currently, we need to give requests manually to get the updated time. On this web application, we can enable the “auto-refresh” feature. You will get this more here:- Auto-refresh feature in Servlet.

Download this example or see the code at GitHub. To use the downloaded file, extract the zip file and deploy the DateApp folder in <Tomcat_home>\webapps folder.

In the next tutorial Servlet Architecture and Workflow, we will discuss the flow of this web application. What is happening when we type URL in the browser, how web.xml file is used in that process, how servlet component is processed, and how second request processing will be different from the first request, and e.t.c.

Understanding Servlet Component

We have successfully developed the simple Java Servlet web application program. Now let us understand the developed Java Servlet program.

public class DateServlet extends HttpServlet

Our class must be public so that the web container can access it from any package. In the servlet introduction, we discussed the different approaches to develop servlet components and their advantages and limitations. We used the third approach i.e. extending our class from HttpServlet class and implementing one of two service(-,-) methods or one of the 7 doXxx(-,-) methods. 

public void service(HttpServletRequest req, HttpServletResponse res)

throws ServletException, IOException

It is the direct method of HttpServlet class. By default it is a protected method but we must override it with a strong accessibility modifier public so that the servlet container can access it.

// set response content type
res.setContentType("text/html");

It gives instructions to the browser through the webserver to display received output content as HTML code bases text documents (web page) on the browser window. You can see more it here:- MIME Type in Java

// get PrintWriter 
PrintWriter pw = res.getWriter();

The response object contains 1 built-in stream PrintWriter. The getWriter() method of the response object returns that stream to the servlet component. This stream points to the response object as the destination object to write the data.

// Get current date and time
Date d = new Date();

// write output message to response object
// using PrintWriter obj
pw.println("<h1>Welcome to Servlet</h1>");
pw.println("<h2>Date and time::"+ d.toString() +"</h2>");

The println(-) method writes the given message to the response object. The response object writes given messages to the web server through ServletContainer. Then the web server writes the given message to browser windows as the web page content.

// close stream
pw.close();

It closes the stream that is associated with the response object i.e. it doesn’t allow to write further content to the response object using that Stream (commits the response).

For every request coming to the Servlet component the Servlet container calls service(-,-) having request, response object as arguments to process the request.

Servlet Configuration File

Servlet configuration means giving the class name and package name of the servlet component to Servlet Container to recognize a given class as a servlet component. Servlet mapping means linking certain request URLs with servlet components asking ServletContainer to allow the request to private area Servlet component for specified request URL.

A servlet component is identified with its mapped URL, so we must use that URL to request the servlet component. The Servlet component is not identified with its class name or logical name. If we try to request the servlet component other than the mapped URL then we will get an error-404 status code.

The web server reads the web.xml file the moment we deploy the web application. So a web.xml file can be called a Deployment Descriptor. It contains a lot of configuration related to web applications so this file is also called a web application configuration file.

<web-app>
   <!--Servlet Configuration-->
   <servlet>
      <servlet-name>date</servlet-name>
      <servlet-class>com.kp.servlet.DateServlet</servlet-class>
   </servlet>

   <!--Servlet Mapping-->
   <servlet-mapping>
      <servlet-name>date</servlet-name>
      <url-pattern>/home</url-pattern>
   </servlet-mapping>
</web-app>

In our Java servlet program we have used this web.xml file. Here:-

  • URL:- /home
  • Logical name:- date
  • Mapped Servlet component:- com.kp.servlet.DateServlet

In one web.xml we configure all the servlet components with URL (but in our example, only one configuration is there). Assume there are 10 servlet components configured in the web.xml. When we make a request “/home” from the browser then the web container first finds the logical name (<servlet-name>) for that URL. In our example, the logical name for “/home” is “date”.

Now, the web container finds the Servlet component having a logical name “date”. In our example “com.kp.servlet.DateServlet” contains the logical name “date” therefore web containers start processing this component.

While developing the web.xml file the logical name of <servlet> tag and the logical name of <servlet-mapping> must match to link/map certain requests.

In http://localhost:8080/DateApp/home,

  • /home:- the URL mapped with servlet component
  • /DateApp:- Web application name
  • 8080:- port number of tomcat server
  • localhost:- host name
  • HTTP:- protocol

We can configure multiple instructions to web container from web.xml file.

  • Servlet or JSP or HTML configuration.
  • Servlet or JSP or HTML mapping with URL/URL patterns.
  • Welcome or home page configuration.
  • Security configuration.
  • Session timeout configuration and e.t.c.

HTTP Status 404 – Not Found

There are many things due to which we can get 404 errors – request resources not found. The main reasons to get 404 error in Java servlet program,

  • Wrong request URL in the browser address bar.
  • Wrong deployment directory structure (i.e. wrong folder names or locations).
  • The wrong entries in the web.xml file. XML is case sensitive and strictly type i.e. every open tag must have a closing tag.
  • Wrong web.xml file name or location. The web.xml file must be inside the WEB-INF folder and outside of the classes folder.

HTTP Status 500 – Internal Server Error

HTTP Status 500 – Internal Server Error, Exception:- jakarta.servlet.ServletException: Error instantiating servlet class. The main reasons to get 500 error in Java servlet program,

  • If the servlet component class is not having a public 0-param constructor directly or indirectly. Root cause:- java.lang.NoSuchMethodException
  • Servlet component class is not taken as public. Root Cause:- java.lang.IllegalAccessException: class org.apache.catalina.core.DefaultInstanceManager cannot access a member of class com.kp.servlet.DateServlet with modifiers “public”
  • Wrong entry for package name in web.xml file in <servlet-class> tag. Root cause:- java.lang.ClassNotFoundException: com.kp.DateServlet

Modifying Source Code of deployed Servlet Component

We already know that a web container needs a .class file, not the .java file. Therefore if we are modifying anything in the .java file of a deployed web application then we must recompile it. The modification done in the source code of the deployment Servlet component will be reflected only after the recompilation of the Servlet component and reloading of the web application.

The reloading can be done from the Manager app. To enter into the manager app, a username and password are required. In the tomcat installation tutorial we discussed how to set, view, and update username, password, and role. There you can find all the deployed web applications, and from there we do reload the web application.

In our example, we want the output at the center of the web page, and in different colors. In order to do that go to the deployed web application=> WEB-INF => classes folder and modify the DateServlet.java file.

// write output message to response object
// using PrintWriter obj
pw.println("<h1 style='color:blue; text-align:center'>Welcome to Servlet</h1>");
pw.println("<h2 style='color:green; text-align:center'>Date and time::"+ d.toString() +"</h2>");

After modification, recompile the DateServlet.java, open the Manager app of the tomcat server, reload the web application and give request to the servlet component through the same URL. 

When we reload the web application then the current web application will be stopped, all existing objects will be destroyed, and then the web application will be restarted. Now, it will load the classes folder and take the updated .class file therefore modification will be reflected.

The modification done in static web components (HTML/CSS, image, audio) and web.xml file of the web application will reflect itself by the servlet container, no need to recompile the servlet component or reload the web application

We need to recompile the servlet component after each modification because the servlet container needs .class not the .java file, and reloading is done to destroy existing objects and create objects for updated servlet components.

Console messages

When we start tomcat server through exe/bat file then one command prompt (console window) appears with all logging messages, and we get “org.apache.catalina.startup.Catalina.start Server startup in [8167] milliseconds”.

What happens if we print messages through System.out.println(-) in servlet component? In the servlet component, the messages kept in pw.println(-) go to the browser through the response object, servlet container, and web server. Whereas the message kept in System.out.println(-) goes to tomcat server as log message/confirmation messages (in the console window). We will see this through example.

How Servlet is Single Instance Component

In servlet definition, we said that the Servlet component is a single instance multiple thread component. How can we prove a servlet is a single instance i.e. it is creating only one object for our servlet class and using that object for all the requests?

There are various ways to create objects of a Java class and most of them are using constructors. So, if the constructor is called only for one time then we can say the servlet component is using a single object or servlet component for all the requests.

Servlet container creates servlet component objects through zero parameter constructor, therefore in our servlet class, zero parameter constructor must be available either directly placed by the programmer or indirectly placed by the compiler. If the programmer manually doesn’t place any constructor in a Java class then only the compiler itself generates one zero parameter constructor called default constructor.

package com.kp.servlet;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import java.io.*;
import java.util.*;
public class DateServlet extends HttpServlet {
   
   // 0-param constructor
   public DateServlet(){
      System.out.println("Zero-Param Constructor");
   }

   public void service(HttpServletRequest req, HttpServletResponse res) 
      throws ServletException, IOException {

      res.setContentType("text/html");
      PrintWriter pw = res.getWriter();
      Date d = new Date();
      pw.println("<h1>Welcome to Servlet</h1>");
      pw.println("<h2>Date and time::"+ d.toString() +"</h2>");
      pw.close();

      // display this message to console whenever service(-,-) is called
      System.out.println("Service(-,-) Method is called: "+d);
   }
}

Modify the servlet component, recompile it, reload the web application, request the mapped URL of this servlet component. Give requests multiple times by refreshing the web page. Now, observe the log messages on the console (not on the browser). We can see the constructor was called only one time but the service(-,-) method is called every time whenever we give the request. For 5 request the message on the console will be like,

Zero-Param Constructor
Service(-,-) Method is called: <current-time>
Service(-,-) Method is called: <current-time>
Service(-,-) Method is called: <current-time>
Service(-,-) Method is called: <current-time>
Service(-,-) Method is called: <current-time>

The above message proves that the constructor is called only once, therefore we can say Servlet is a single instance component.

If servlet component doesn’t contain any zero-param constructor then we will get error:- “HTTP Status 500 – Internal Server Error” with exception message:- “jakarta.servlet.ServletException: Error instantiating servlet class [com.kp.servlet.DateServlet]”.

In the above servlet component, replace the existing zero parameter constructor with given below one-parameter constructor and try it yourself. Default constructors will be generated only if no constructor is placed by the programmer. Note:- If the constructor is not public then also we will get the same error.

// 1-param constructor
public DateServlet(String s){
   System.out.println("One-Param Constructor");
}

In servlet component the constructor must be,

  • public
  • zero parameter

To avoid memory wastage, the servlet container creates only one object for one servlet component and uses it for all the requests given to that particular servlet component. For a 100000 request given to a servlet component only one object of the servlet component will be used.

How Servlet is Multiple Thread Component

If we give 100 requests to our servlet component then Servlet container creates

  • 1 object for servlet component class
  • 100 sets of request, response objects representing requests
  • 100 threads representing 100 requests
Servlet in Java

For every request given to the Servlet component, the Servlet container creates 1 thread and 1 set of request, response objects, and those objects will be destroyed once the request-related response goes to the browser window.

All the above points prove single instance multiple threads behavior. To prove the above points practically we can take the help of hashcode value. For every object, JVM generates one unique identification number called hashcode value, and to get that hashcode value we can use the hashcode() method of java.lang.Object class.

Place the below logic in the service(-,-) method before closing the stream. Give requests from multiple tabs of a browser or from multiple browsers in the computer.

pw.println("<br>Request Object hashcode: " + req.hashCode());
pw.println("<br>Response Object hashcode: " + res.hashCode());
pw.println("<br>Our Servlet class Object hashcode: " + this.hashCode());
pw.println("<br>Our Current Request Thread Object hashcode: " +
                Thread.currentThread().hashCode());

We will never get the same hashcode for request, response, and thread. But the hashcode for the servlet class object will remain the same for all those requests. It proves the servlet is a single instance and multiple thread component.

URL Pattern

1) We can map one servlet component with multiple URL patterns.

<!--Servlet Configuration-->
<servlet>
   <servlet-name>date</servlet-name>
   <servlet-class>com.kp.servlet.DateServlet</servlet-class>
</servlet>
<!--Servlet Mapping-->
<servlet-mapping>
   <servlet-name>date</servlet-name>
   <url-pattern>/home</url-pattern>
   <url-pattern>/test</url-pattern>
</servlet-mapping>

Now, we can access the DateServlet component from http://localhost:8080/DateApp/test and http://localhost:8080/DateApp/home 

2) We can use URL patterns to hide the technologies of the web application. 

With the support of mapped URLs of servlet components, we can hide the technology of web applications in which it is being developed. This process may give protection to the web application.

<servlet-mapping>
   <servlet-name>date</servlet-name>
   <url-pattern>/home.php</url-pattern>
</servlet-mapping>

Now, based on the URL pattern we can’t guess the technology name. The DateServlet is actually developed in Java, but based on the URL we can assume that the web components are developed in PHP.

3) With the URL pattern we can hide the folder hierarchy.

<servlet-mapping>
   <servlet-name>date</servlet-name>
   <url-pattern>/welcome/knowprogram/home</url-pattern>
</servlet-mapping>

Now this Java servlet program, can be accessed through http://localhost:8080/DateApp/welcome/knowprogram/home. But in reality, there is not any folder “welcome”, and “knowprogram” in the current web application.

It is very useful when the servlet component is at a deep hierarchy, then we can use a simple URL to access them (opposite to the above example, where the component is not deep but the URL is deep).

Summary

  • The modification done in the static web component (HTML/CSS, image, audio) and web.xml file of the web application will reflect itself by the servlet container, no need to reload the web application. 
  • Whereas the modifications done in the source code of the servlet component will reflect only after recompilation of the servlet component and reloading the web application.
  • In the deployment directory structure of the Java web application, only 4 standard names are there. They are:- a)WEB-INF, b)classes, c)web.xml, d)lib, and all these belong to the private area of the web application. The remaining all folder and file names develop choice names.
  • The System.out.println(-) message placed in the Servlet component will be displayed on the server console(window representing servers demon process) as a debug message. The messages kept in pw.println(-) go to the browser through the response object, servlet container, and web server.
  • The servlet container uses a public 0-param constructor while instantiating our servlet class (object creation). Therefore public 0-param constructor must be available in our servlet component either directly or indirectly.
  • For every request given to the Servlet component, the Servlet container creates 1 thread and 1 set of request, response objects, and those objects will be destroyed by the web container, once the request-related response goes to the browser window.
  • Using the URL pattern we can hide the servlet class name, technology name from the visitor of the websites. This helps to improve the security of the web application towards getting protection from hackers.

Other points

  • In one computer we can install multiple web servers but at different port numbers.
  • A web server can contain multiple web applications, but generally, in real-time we prefer one web application (one project) on one web server.
  • A web application will contain multiple servlet components and they will be configured with an URL pattern through a web.xml file.

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or you find anything incorrect? Let us know in the comments. Thank you!

Leave a Reply