ServletContext Interface with Example

In the previous tutorial, we discussed the ServletConfig object which is one per servlet component. Now, let us discuss the ServletContext object which is also created by the servlet container but there will be only one ServletContext object per web application, therefore it is also called as global memory of the web application. Later we will discuss the difference between ServletContext and ServletConfig i.e. init-param vs context-params.

Properties of ServletContext object

  1. ServletContext object is one per web application, so it is also called Global memory of web application.
  2. This object is visible and accessible in all the servlet/jsp components of the web application.
  3. Servlet Container creates this object either during Server startup or during the deployment of a web application.
  4. Servlet Container destroys this object when the web application is stopped/reloaded/undeployed.
  5. It is the object of ServletContainer supplied Java class that implements jakarta.servlet.ServletContext(I).

Note that a web server can contain multiple web applications.

Context Parameters (<context-param>)

The values/data passed through <context-param> of web.xml will be stored in the ServletContext object.

<web-app>
   <context-param>
      <param-name>URL</param-name>
      <param-value>jdbc:oracle:thin:@localhost:1521:knowprogram</param-value>
   </context-param>
   <context-param>
      <param-name>dbuser</param-name>
      <param-value>scott</param-value>
   </context-param>
   <context-param>
      <param-name>dbpass</param-name>
      <param-value>tiger</param-value>
   </context-param>
</web-app>

How is it stored? We deploy the web application, Servlet container verifies the deployment directory structure and loads web.xml file, checks whether web.xml is well-formed and valid or not, if yes then creates its in-memory metadata. Now, the servlet container creates one ServletContext object, checks in-memory metadata to find if there are any context-param values? If yes then take them and store them in the ServletContext object. 

Since it is the global memory of the web application, therefore we pass those values using <context-param> which will be used in multiple servlet/JSP components. For example:- In the web application there are multiple servlet/JSP components that need to talk to database software. To communicate with the database they need a URL, database username, and password. We shouldn’t hardcode those values in every servlet/JSP component because due to security reasons, the username and password will be changed after every some time period. And instead of passing those values for every servlet component using <init-param> and ServletConfig object, we should use context-param values and ServletContext objects.

GetServletContext() Method

There are different ways of accessing ServletContext objects.

a) With the help of ServletConfig object.

Access ServletConfig object of the Servlet class and using it access the ServletContext object of the web application. The getServletContext() method is available in the ServletConfig interface.

ServletConfig cg = getServletConfig();
ServletContext cs = cg.getServletContext();

b) Directly call getServletContext() method of GenericServlet abstract class.

ServletContext cs = getServletContext();

Internally this method uses the previous approach (a). Most of the time we use this approach compared to others.

c) From Servlet API 3.x we can call getServletContext() method on request object to access the ServletContext object.

ServletContext sc = req.getServletContext(); 

But the limitation of this approach is:- The request object will be available only in service and doXxx(-,-) methods therefore we can’t use this approach to get data in init() and destroy() methods.

Example

Example of accessing ServletContext object and gathering <context-param> data from the above web.xml file. In the Servlet component,

// get ServletContext
ServletContext sc = getServletContext();
// get context params
String url = sc.getInitParameter("URL");
String user = sc.getInitParameter("dbuser");
String pass = sc.getInitParameter("dbpass");
// use data to get database connection

Servlet to Database Communication using context param values

Instead of placing the same init param values in multiple Servlet Components of a web application through web.xml file configurations, it is recommended to place them as context-param values only for 1 time in the web.xml file by using <context-param>, <param-name>, <param-value> tags.

Web Application Description:- In the MySQL database, we have a “student” table. In web applications, there will be an HTML form that gets the student number (sno) as input and passed to the servlet component. Based on the passed sno fetch sname, sadd, and avg of student and display them as result. Use context-param to pass driver class name, database URL, username, and password. Get more about Java to database connectivity here:- Java to MYSQL connection in Eclipse.

snosnamesaddavg
10SophiaManchester72
11WilliamWashington80
12AlexBoise95
13AmeilaLondon85
Database Connectivity in Servlet - HTML Form - ServletContext Object
HTML Form
Database Connectivity in Servlet - Student Found and Details displayed
Output for the valid Student number
Database Connectivity in Servlet - Student not found
Output for the invalid Student number

Add MySQL-connector.jar file to the webapp\WEB-INF\lib folder. The HTML file (form.html),

<h1 style="color:blue">Find Student details</h1>
<form action="student-details" method="post">
   Student No: <input type="text" name="sid"/><br>
   <input type="submit" value="Get Student Details">
   <input type="reset" value="Cancel">
</form>

The deployment descriptor (web.xml) file,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xsi:schemaLocation=
"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
   id="WebApp_ID" version="4.0">
   <display-name>ServletToDBcontextParam</display-name>
   <welcome-file-list>
      <welcome-file>form.html</welcome-file>
   </welcome-file-list>
   <context-param>
      <param-name>driver-class-name</param-name>
      <param-value>com.mysql.cj.jdbc.Driver</param-value>
   </context-param>
   <context-param>
      <param-name>URL</param-name>
      <param-value>jdbc:mysql:///knowprogram</param-value>
   </context-param>
   <context-param>
      <param-name>dbuser</param-name>
      <param-value>root</param-value>
   </context-param>
   <context-param>
      <param-name>dbpass</param-name>
      <param-value>[email protected]</param-value>
   </context-param>
   <servlet>
      <servlet-name>student</servlet-name>
      <servlet-class>com.kp.servlet.GetStudentServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>student</servlet-name>
      <url-pattern>/student-details</url-pattern>
   </servlet-mapping>
</web-app>

The servlet component (GetStudentServlet.java),

package com.kp.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class GetStudentServlet extends HttpServlet {
   // SQL query
   private static final String SELECT_STUDENT_QUERY = 
         "SELECT SNAME, SADD, AVG FROM STUDENT WHERE SNO = ?";
   
   @Override
   public void doGet(HttpServletRequest req, HttpServletResponse res) 
         throws ServletException, IOException {
      
      // variables
      PrintWriter pw = null;
      int sno = 0;
      ServletContext sc = null;
      String driverclass = null;
      String url = null;
      String dbuser = null;
      String dbpwd = null;
      Connection con = null;
      PreparedStatement ps = null;
      ResultSet rs = null;
      boolean flag = false;
      
      // set content type
      res.setContentType("text/html");
      // get Writer
      pw = res.getWriter();

      // get form data
      sno = Integer.parseInt(req.getParameter("sid"));
      
      // get ServletContext object
      sc = getServletContext();
      // get context-param values
      driverclass = sc.getInitParameter("driver-class-name");
      url = sc.getInitParameter("URL");
      dbuser = sc.getInitParameter("dbuser");
      dbpwd = sc.getInitParameter("dbpass");
      
      try {
         // register JDBC driver
         Class.forName(driverclass);
         // create JDBC connection
         con = DriverManager.getConnection(url, dbuser, dbpwd);
         // compile SQL query and store it in
         // PreparedStatement object
         if (con != null)
            ps = con.prepareStatement(SELECT_STUDENT_QUERY);
         // set input value to query parameter
         if (ps != null)
            ps.setInt(1, sno);
         // execute the query
         if (ps != null)
            rs = ps.executeQuery();

         // process the result
         if (rs != null) {
            while(rs.next()) {
               // display result
               flag = true;
               pw.println("<h1>Student Details, </h1>"
                     + "Name: " + rs.getString("SNAME") + "<br>"
                     + "Address: " + rs.getString("SADD") + "<br>"
                     + "Average: " + rs.getDouble("AVG") + "<br>");
            }
         }
         
         // Student not found
         if(!flag) {
            pw.println("<h1>Student Not Found.</h1>");
         }

      } catch (SQLException se) {
         se.printStackTrace();
         pw.println("Error Occured");
      } catch (Exception e) {
         e.printStackTrace();
         pw.println("Unknown Exception Occured");
      } finally {
         // close JDBC connection
         try {
            if (rs != null)
               rs.close();
         } catch (SQLException se) {
            se.printStackTrace();
         }
         try {
            if (ps != null)
               ps.close();
         } catch (SQLException se) {
            se.printStackTrace();
         }
         try {
            if (con != null)
               con.close();
         } catch (SQLException se) {
            se.printStackTrace();
         }

         // Link to home
         pw.println("<h3><a href='form.html'>Home</a></h3>");
         // close stream
         pw.close();
      }
   }

   @Override
   public void doPost(HttpServletRequest req, HttpServletResponse resp) 
         throws ServletException, IOException {
      doGet(req, resp);
   }
}

See the source code of this web application at GitHub.

Uses of ServletContext Object

Using the ServletContext object we can gather multiple details,

  • Server information.
  • Servlet API version supported by the server.
  • The MIME-type or content type of the given file.
  • InputStream pointing to a given resource.
  • To read global init param values/Context param values from web.xml to our Servlet component.
  • To get the path of a certain resource of the server machine file system.
  • From servlet 3.x onwards, using ServletContext object we can configure the servlet with URL pattern without using web.xml and annotations. We can configure the URL pattern with the servlet component using three approaches:- 1) web.xml file, 2) Annotation, 3) Java code (using ServletContext object).
  • To write messages to log files.
  • To get the context path name of the web application.
  • Get the path of the deployed web application from the server.

Important Methods of ServletContext Interface

Method Description
String getInitParameter(String name)Returns a string containing the value of the named context-wide initialization parameter, or null if the parameter does not exist.
Enumeration<String> getInitParameterNames()Returns the names of the context’s initialization parameters as an Enumeration of String objects, or an empty Enumeration if the context has no initialization parameters.
int getMajorVersion()Returns the major version of Jakarta Servlet that this container supports.
String getMimeType(String file)Returns the MIME type of the specified file, or null if the MIME type is not known.
int getMinorVersion()Returns the minor version of Jakarta Servlet that this container supports.
String getRealPath(String path)Gets the real path corresponding to the given virtual path.
URL getResource(String path)Returns a URL to the resource that is mapped to the given path.
String getServerInfo()Returns the name and version of the servlet container on which the servlet is running.
SessionCookieConfig getSessionCookieConfig()Gets the SessionCookieConfig object through which various properties of the session tracking cookies created on behalf of this ServletContext may be configured.
int getSessionTimeout()Gets the session timeout in minutes that are supported by default for this ServletContext.
void log(String msg)Writes the specified message to a servlet log file, usually an event log.

Get more methods with their purpose from here.

Using ServletContext object we can gather flowing miscellaneous information,

public void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
   // get PrintWriter
   PrintWriter pw = resp.getWriter();
   // get ServletContext object 
   ServletContext sc = getServletContext();
   // get server info
   pw.println("<br> Server info: "+ sc.getServerInfo());
   // get servlet api version
   pw.println("<br> Servlet API version: "+ sc.getMajorVersion()
              +"."+sc.getMinorVersion());
   // get real path of the web application
   pw.println("<br> Real path of the web application: "+ sc.getRealPath("/"));
   // get real path of files
   pw.println("<br> Real path of input.html: "+ sc.getRealPath("/input.html"));
   // get MIME type
   pw.println("<br> MIME type of input.html: "+ sc.getMimeType("input.html"));
   // write message to log file
   sc.log("System Date: "+ new java.util.Date());
}

Output on browser:-

Server info: Apache Tomcat/10.0.5
Servlet API version: 5.0
Real path of the web application: D:\workspace\Servlet.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Test\
Real path of input.html: D:\workspace\Servlet.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Test\input.html
MIME type of input.html: text/html

Output on console (log message):-

INFO: System Date: Wed May 19 21:42:49 IST 2021

FAQ

Question) What happens if multiple context params of a web application are having the same name and different values? Which will be considered?

<context-param>
   <param-name>dbuser</param-name>
   <param-value>scott</param-value>
</context-param>
<context-param>
   <param-name>dbuser</param-name>
   <param-value>user1</param-value>
</context-param>

In the servlet component,

// get ServletContext
ServletContext sc = getServletContext();
// get context params
String user = sc.getInitParameter("dbuser");

Answer:- If multiple context params of a web application are having the same name with different values then the last value will be considered. In the above situation, “user1” will be taken as a context-param value.

If we give the same name to multiple context parameters we can get an exception in tomcat 6, 7 servers but we get a 2nd value in tomcat 8/9/10 server.

Q) Where is ServletContext?
ServletContext is an object of jakarta.servlet.ServletContext(I) created by the servlet container. It is one per web application which is visible and accessible in all the servlet/JSP components of the web application. Therefore it is also called the global memory of a web application.

Q) How many ServletContext is available for an entire Web application?
Only one. ServletContext object is one per web application which is visible and accessible in all the servlet/JSP components of the web application.

Q) How many ServletContext objects is created?
Only one per web application. Servlet container creates only one ServletContext object per web application.

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 Comment

Your email address will not be published. Required fields are marked *