Servlet setup

All lectures for EN purposes
Level 1 , Lesson 318
Available

init() method

And a couple of other useful little things. Of course, I'm talking about servlet initialization. As you already know, after the web server has created the servlet object and placed it in the container, it calls the servlet's init() method . You can override this method and initialize whatever you need in it.

Why not use a constructor?

Because the process of creating a servlet goes something like this:

  • We create an object inherited fromHttpServlet
  • Create an objectServletContext, add its servlet variable
  • Create an objectServletConfig, add its servlet variable
  • Web server attaches servlet to container
  • Calling the init() method

In the constructor of your servlet, a lot of its internal variables are still not initialized. The container knows nothing about your servlet, your servlet knows nothing about its context. I think everything is clear here.

Let's write a servlet that, when initialized, finds a properties file with settings:

public class PropertiesServlet extends HttpServlet {
    public init() {
         try (InputStream input = new FileInputStream("c:/path/to/config.properties")) {

             Properties prop = new Properties();
             prop.load(input);

             String databaseURL = prop.getProperty("db.url");
             String databaseUser = prop.getProperty("db.user ");
             String databasePassword = prop.getProperty("db.password");
	 }
  }
}

Here we create an objectPropertiesand load data from the config.properties file into it . Well, in the future you can get out of the objectPropertiesvarious options such as data to access the database, eg.

How to load the properties file correctly

By the way, what if your servlet is not running on your computer?

Let's say they wrote it here, and it runs on a server somewhere in another part of the world. Or multiple servers. How to load the properties file correctly in this case?

Good question. Normally, when running, a servlet only knows the relative path of its properties files, not its absolute path, because servlet war files can be stored anywhere.

So, we need to find out the path where our servlet is stored (the servlet is already initialized) and add a relative path to it :)

It looks something like this:

String path = absoluteServletParh + "relative path";

And, as always, such an elementary task often has its own little “but”. Your servlet and its properties file are stored inside the archive :) Not necessarily, of course, but it happens. properties file is often stored inside jar or war files.

That is, your file may not have a physical path on the disk. But since the container was able to load your servlet, it will most likely be able to load your properties file as well.

To do this, you need to get the class loader object (ClassLoader) and ask him to upload your file. Here's what it will look like:

ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream stream = loader.getResourceAsStream("/config.properties");

Properties prop = new Properties();
prop.load(stream);

getConfig() Method

By the way, not all parameters can be passed to the servlet in properties files. For example, your servlet communicates with other servlets in a distributed web application.

Then you need to make sure that the container passes all the necessary information to your servlet when it calls its init() method . Moreover, he does just that.

Your servlet (remember that it's inherited from the HttpServlet class ) has a getServletConfig() method . which returns an objectServletConfig, created and initialized by the container. This object has the following methods:

getInitParameterNames() Returns a list of servlet parameter names
getInitParameter(String name) Returns a servlet parameter by its name
getServletName() Returns the servlet's own name
getServletContext() Returns an objectServletContext

Let's write a servlet that returns a list of its parameters fromServletConfig'A. Putting them there will be through the web.xml file:

	<web-app> 
 	
        <servlet> 
            <servlet-name>Print-Servlet</servlet-name> 
            <servlet-class>PrintServlet</servlet-class> 
            <init-param> 
                <param-name>jdbc-driver</param-name> 
    	        <param-value>sun.jdbc.odbc.JdbcOdbcDriver</param-value> 
	        </init-param> 
        </servlet> 
  	
        <servlet-mapping> 
            <servlet-name>Print-Servlet</servlet-name> 
            <url-pattern>/print</url-pattern> 
        </servlet-mapping> 
  	
    </web-app>

A servlet can get its parameters using the code:

public class PrintServlet extends HttpServlet {
    public void init() {
        ServletConfig config = this.getServletConfig();
        Enumeration<String> initParameterNames = config.getInitParameterNames();

        while (initParameterNames.hasMoreElements()){
       	     String key = initParameterNames.nextElement();
             System.out.println("%s: %s\n", key, config.getInitParameter(key));
    	}
  }
}
Comments (2)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Thomas Level 41, Bayreuth, Germany
15 March 2024
OK, there are two ways to store config info. a) application context done in web.xml, eg.

    <context-param>
        <param-name>jdbcDriver</param-name>
        <param-value>oracle.jdbc.OracleDriver</param-value>
    </context-param>
    <context-param>
        <param-name>propertiesPath</param-name>
        <param-value>c:\settings\config.properties</param-value>
    </context-param>
Then in your servlet you read these config parameters using:

        final ServletContext application = getServletContext();
        final String jdbcDriver = application.getInitParameter("jdbcDriver"); // getInitParameter - context is container
        final String propertiesPath = application.getInitParameter("propertiesPath");
b) servlet context above you can see the declaration of some servlet init parametes using the deployment descriptor There is another possibility to declare servlet config parameters using the WebServlet annotation, eg.

@WebServlet(
        value = "/initTest",
        initParams = {
                @WebInitParam(
                        name = "settingsPathInternal",
                        value = "/WEB-INF/db.properties"),
                @WebInitParam(
                        name = "settingsPathExternal",
                        value = "c:\\settings\\db.properties")
        })
public class InitTestServlet extends HttpServlet {
Because you want the settings to be modifiable without having to redeploy the application, it does not really make sense to use this to add the final settings but just to give a path to a settings file. The external file is pretty cool as you can modify it without any problems. The WEB-INF path is still internal but the properties file is not compiled and hence changeable.
Thomas Level 41, Bayreuth, Germany
15 March 2024
Now how to save internal (inside the WEB-INF directory -> I use that as it is not readable from the web, just your servlet has access) and external (somewhere on your PC) a) WEB-INF directory... contrary to what CodeGym says you do not need the way via the class loader. You just ask the container to provide the InputStream. In the example below the above configuration via annotation is used

        final String settingsPathInternal = getInitParameter("settingsPathInternal"); // getInitParameter - context is servlet

        final ServletContext application = getServletContext(); 
        final InputStream in = application.getResourceAsStream(settingsPathInternal);

        final Properties properties = new Properties();
        properties.load(in);
b) to load some properties file somewhere on your PC you just use NIO (the Files class) and ask for an InputStream

        final String settingsPathExternal = getInitParameter("settingsPathExternal");
        final Properties properties = new Properties();

        try (final InputStream in = Files.newInputStream(Paths.get(settingsPathExternal))) {
            properties.load(in);
        } catch (IOException ioe) {
            throw new ServletException(ioe); // change to logging or whatever necessary
        }
Note: code may contain typos