ServletConfig Interface with Examples

The ServletConfig object is created by Servlet Container one for each servlet component. This object is specific to one servlet component. Following are main important points on ServletConfig interface in Servlet API:-

  1. ServletConfig object is one per Servlet class object.
  2. Servlet Container creates this object either during Server startup or during the deployment of the web application based on Servlet configuration done in the web.xml file.
  3. Every servlet component related ServletConfig object will be handed over to the servlet class through the init(ServletConfig cg) method, which is a life cycle method of servlet performing initialization operations.
  4. Servlet Container destroys this object right after Servlet class object destruction.
  5. It is the object of the servlet container supplied Java class that implements jakarta.servlet.ServletConfig(I).
  6. ServletConfig is useful to pass additional information to Servlet and to gather information about servlet components.
  7. It can be used to gather init param values from the web.xml file to the Servlet component.
  8. It can be used to access ServletContext objects.

Example:- During deployment of the web application, the servlet container finds 20 servlet components in the web.xml file, then it will create 20 ServletConfig objects on one per servlet component configuration basis. When each servlet class is created either through <load-on-startup> process or when it gets the first request, then every servlet related ServletConfig object will be handed over to that particular servlet class through the life-cycle method init(ServletConfig cg). 

If we want to know additional information about the servlet or we want to know about the servlet being from the servlet then we will use this ServletConfig object.

Reading Initialization Parameters in Servlets through getServletConfig()

Servlet component can get input values in two ways:-

  • For non-technical inputs from end-user (client-side):- In this way we use the HTML form component, those input values are passed to the servlet component through the request object and we can get them through req.getParameter(-) method.
  • For technical inputs:- the technical inputs like database URL, username, password, JDBC driver class name are passed through a configuration file (web.xml) as initialization parameter or context parameters. 

The initialization parameters in the servlet are given in the web.xml file through <init-param> will be passed to the servlet component. 

<?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"
   version="4.0">
   <servlet>
      <servlet-name>emp</servlet-name>
      <servlet-class>com.kp.servlet.GetEmployee</servlet-class>
      <init-param>
         <param-name>dbuser</param-name>
         <param-value>scott</param-value>
      </init-param>
      <init-param>
         <param-name>dbpass</param-name>
         <param-value>tiger</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>emp</servlet-name>
      <url-pattern>/getemp</url-pattern>
   </servlet-mapping>
</web-app>

How initialization parameter values are stored in servlet container?:- we deployed the web application, servlet container verifies the deployment directory structure, then it loads web.xml file and checks if it is well-formed and valid or not, then it creates in-memory metadata of web.xml file. Since only one servlet component is configured in the above web.xml file, therefore, the servlet container will create only one ServletConfig object. By default ServletConfig object holds the logical name of the servlet class. Then it checks if there any init-param values for that particular servlet component? If yes then store-related init-param values in the ServletConfig object.

When the servlet container gets the first request for the servlet component then it loads and creates an object for that servlet class. After object creation, instantiation event raises and init(ServletConfig cg) method will be called. In that process, the ServletConfig object will be passed as an argument value. To use init-parm values which are available in ServletConfig objects, the getInitParameter(-) method can be used.

Different ways of getting access to ServletConfig object

Approach-1:- Using init() method. The init() method is a life cycle method and we can override them in our servlet class.

public class TestServlet extends HttpServlet {
   private ServletConfig cg;

   @Override
   public void init(ServletConfig cg) {
      this.cg = cg;
      // use cg here
   }

   @Override
   public void doGet(HttpServletRequest req, HttpServletResponse resp) 
       throws ServletException, IOException {
      // use cg here
   }
}

Limitation of this approach:- We must remember and initialize ServletConfig objects with instance variables otherwise we can’t access ServletConfig objects in the doXxx(-,-) methods. Therefore this approach is not recommended to use.

Approach-2:- Using getServletConfig() method. This method is defined in the GenericServlet class and can be used to access the ServletConfig object.

public class TestServlet extends HttpServlet {
   @Override
   public void doGet(HttpServletRequest req, HttpServletResponse resp) 
       throws ServletException, IOException {
      ServletConfig cg = getServletConfig();
   }
}

Approach-2 is good because we need not initialize ServletConfig obj explicitly. The GenericServlet’s init(-) method will take care of that, we just need to call the getServletConfig() method to get access to that object.

For the above web.xml file we can access them in servlet class as,

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) 
     throws ServletException, IOException {
   // get access to ServletConfig object
   ServletConfig cg = getServletConfig();
   // read init-param values
   String user = cg.getInitParameter("dbuser");
   String pwd = cg.getInitParameter("dbpass");
   // use values
   System.out.println(user +" "+ pwd);
}

It will give the following output:-

scott tiger

The servlet init parameters are specific to that servlet for which they are configured because they allocate memory inside the servlet config object that is specific to the servlet.

getInitParameter() vs getInitParameterNames()

Both methods are given in GenericServlet class and can be used to get access to the ServletConfig object. In getInitParameter() we have to pass an argument as a string and it returns only one value specific to that argument but the getInitParameterNames() method returns all init parameter names.

We have already seen an example of getInitParameter(String str). Now let us see example of getInitParameterNames() method:-

@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) 
      throws ServletException, IOException {
   // get access to ServletConfig object
   ServletConfig cg = getServletConfig();
   // get all init param names
   Enumeration<String> e = cg.getInitParameterNames(); 
   while(e.hasMoreElements()) {
      // get each init param name
      String name = (String) e.nextElement(); 
      // get each init param value
      String value = cg.getInitParameter(name);
      // use init-param values
      System.out.println( name + ":: " + value );
   }
}

It gives the following data:-

dbpass:: tiger
dbuser:: scott

ServletConfig Example

Here we will see the Servlet to Database communication using init param values.

In servlet to database communication, we need to gather the driver class name, URL pattern, username, and password of the database software. For security reasons, the username and passwords are changed frequently. Similarly, when an application is hosted from one computer to another computer, the URL pattern may change because it depends on the <host_name> and <port_number>. 

The standard principle of the software industry is don’t hard code any values in our application that are changeable in the future. It is recommended to pass such values to the application form outside the application. We can pass them as <init-parm> or <context-param> values. Let us see how to pass them as <init-param> values and gather them through the getServletConfig() method.

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 passes it to the servlet component. Based on the passed sno fetch sname, sadd, and avg of student all display as result. Use init-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 - ServletConfig object
HTML Form
Database Connectivity in Servlet - Student Found and Details displayed
Output when student found.
Database Connectivity in Servlet - Student not found
Output when student not found.

Add MySQL-connector.jar file to the lib folder of the webapp. 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>ServletToDBInitParam</display-name>
   <welcome-file-list>
      <welcome-file>form.html</welcome-file>
   </welcome-file-list>
   <servlet>
      <servlet-name>student</servlet-name>
      <servlet-class>com.kp.servlet.GetStudentServlet</servlet-class>
      <init-param>
         <param-name>driver-class-name</param-name>
         <param-value>com.mysql.cj.jdbc.Driver</param-value>
      </init-param>
      <init-param>
         <param-name>URL</param-name>
         <param-value>jdbc:mysql:///knowprogram</param-value>
      </init-param>
      <init-param>
         <param-name>dbuser</param-name>
         <param-value>root</param-value>
      </init-param>
      <init-param>
         <param-name>dbpass</param-name>
         <param-value>Know9@Program</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>student</servlet-name>
      <url-pattern>/student-details</url-pattern>
   </servlet-mapping>
</web-app>

The Servlet Component (GetStudentServlet.java) file,

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.ServletConfig;
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;
      ServletConfig cg = 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 ServletConfig object
      cg = getServletConfig();
      // get init-param values
      driverclass = cg.getInitParameter("driver-class-name");
      url = cg.getInitParameter("URL");
      dbuser = cg.getInitParameter("dbuser");
      dbpwd = cg.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 this web application code developed through Eclipse IDE at GitHub.

Methods of ServletConfig Interface

The ServletConfig interface contains a total of four methods. They are:-

Return type MethodDescription
String getInitParameter(String name)Gets the value of the initialization parameter with the given name.
Enumeration<String>getInitParameterNames()Returns the names of the servlet’s initialization parameters as an Enumeration of String objects, or an empty Enumeration if the servlet has no initialization parameters.
ServletContextgetServletContext()Returns a reference to the ServletContext in which the caller is executing.
StringgetServletName()Returns the name of this servlet instance.

Limitation of ServletConfig

The init params are specific to each Servlet Component for which they are configured. For example, If we have 2 servlet components then we need to place the init-param values in both servlet components like below,

</web-app>
   <servlet>
      <servlet-name> Servlet1 </servlet-name>
      <servlet-class>…...</servlet-class>
         <init-param>
            ……..
         </init-param>
    </servlet>
   <servlet>
      <servlet-name> Servlet2 </servlet-name>
      <servlet-class>…...</servlet-class>
         <init-param>
            ……..
         </init-param>
   </servlet>
</web-app>

For example, there are two servlet components that need to talk to database software, in that case, the init-param values must be given for both servlet components. 

To solve this problem we can use context params which are accessed through ServletContext objects. The context params are common for multiple Servlet Components of the web application.

FAQ

Q) What happens if multiple init params of a servlet are having the same name with different values?

<init-param>
   <param-name>dbuser</param-name>
   <param-value>scott</param-value>
</init-param>
<init-param>
   <param-name>dbuser</param-name>
   <param-value>user1</param-value>
</init-param>
<init-param>
   <param-name>dbuser</param-name>
   <param-value>user2</param-value>
</init-param>

In Servlet,

// get access to ServletConfig object
ServletConfig sc = getServletConfig();
// read init-param values
String user = cg.getInitParameter("dbuser");

Answer:- If multiple init params of a servlet are having the same name with different values then the first value will be considered. In the above situation, “scott” will be taken as an init-param value.

Q) Why are we not using properties files to supply JDBC properties?
We have two ways to supply the JDBC properties dynamically to the servlet component either by using the “properties file” or by using the “web.xml” file. We can take properties files having JDBC properties but not recommended because already we have web.xml for regular servlet configurations. So instead of creating a separate file (i.e. properties files) to supply JDBC properties, it is better to use the existing web.xml file to supply JDBC properties.

Q) Can we take the same init-param name and values in two different servlet components configurations?
Yes. The ServletConfig for both servlet components will be two different objects, therefore they can hold init-param with the same name.

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do 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 *