Programming

Where to place and how to read configuration resource files in servlet based application

27 September 2026 · 11 min read

Where to place and how to read configuration resource files in servlet based application

Understanding where to place and how to read configuration resource files in a servlet-based application is crucial for managing application settings efficiently and maintaining a clean, organized project structure. These configuration files, which can include properties files, XML files, or even YAML files, dictate various aspects of your application’s behavior, from database connection details to UI customizations. Incorrectly placed or improperly read configuration files can lead to runtime errors, security vulnerabilities, and significant maintenance headaches. This article will guide you through the best practices for managing configuration resource files in servlet-based applications, ensuring a robust and easily maintainable application.

Best Practices for Placing Configuration Resource Files

The location of your configuration resource files significantly impacts the application’s maintainability and deployment. While there are several options, some are more advantageous than others. A common mistake is hardcoding configuration values directly into the application code. This practice makes it difficult to update settings without recompiling and redeploying the application. Instead, storing these values in external files provides flexibility and allows for dynamic configuration changes without altering the core application logic. Let’s delve into the recommended locations.

One popular approach is placing configuration files within the WEB-INF directory of your web application. The WEB-INF directory is a protected area of the web application archive (WAR) file, meaning that files within this directory are not directly accessible to web browsers. This makes it a secure location for sensitive configuration data, such as database passwords or API keys. You can create subdirectories within WEB-INF, such as WEB-INF/config, to further organize your configuration files. This keeps your project neat and easy to navigate. The security benefit is paramount, protecting sensitive information from unauthorized access.

Another viable option is placing configuration files on the application server’s classpath. This can be achieved by placing the files in a directory that is included in the server’s classpath configuration. For example, in Tomcat, you can place the files in the lib directory or a custom directory defined in the server’s configuration. This approach allows multiple web applications to share the same configuration files, promoting code reuse and consistency across applications. However, it’s important to manage classpath dependencies carefully to avoid conflicts between different applications. According to a survey by Snyk, misconfigured classpaths account for a significant percentage of Java application vulnerabilities. Snyk’s security blog offers further insights into Java security best practices.

Methods for Reading Configuration Resource Files

Once you’ve decided where to place your configuration files, the next step is to read them into your application. Java provides several mechanisms for accessing resources, each with its own advantages and disadvantages. Choosing the right method depends on the file format, the location of the file, and the desired level of flexibility.

For simple properties files, the java.util.Properties class provides a straightforward way to load key-value pairs into memory. You can use the Properties.load(InputStream) method to read the file from an InputStream. To obtain the InputStream, you can use ServletContext.getResourceAsStream(String path) if the file is located within the WEB-INF directory, or ClassLoader.getResourceAsStream(String name) if the file is on the classpath. The ServletContext method is particularly useful because it handles relative paths within the web application archive. This method is ideal for simple configuration settings, such as database URLs or API endpoint addresses.

For more complex configuration files, such as XML or YAML, you might consider using dedicated libraries like Apache Commons Configuration or Jackson. These libraries provide more advanced features, such as support for hierarchical configurations, data validation, and automatic type conversion. For example, Apache Commons Configuration allows you to read configurations from various sources, including properties files, XML files, and databases, using a consistent API. This simplifies the process of switching between different configuration sources. Using external libraries adds dependencies, but it also provides robust and well-tested solutions for managing complex configurations. Using such libraries promote a separation of concerns, making your code cleaner and easier to maintain. Here is an example of using Apache Commons Configuration:

Configuration config = new PropertiesConfiguration("config.properties"); String databaseUrl = config.getString("database.url"); 

Servlet Context and ClassLoader: Key Differences

Understanding the difference between using ServletContext and ClassLoader for accessing resources is crucial for ensuring that your application can locate configuration files correctly. ServletContext provides access to resources within the web application’s context, while ClassLoader provides access to resources on the application’s classpath. Choosing the right method depends on where you’ve placed your configuration files and how you intend to deploy your application.

The ServletContext is an interface that represents the web application’s environment. It provides methods for accessing resources within the web application’s archive (WAR file). When you use ServletContext.getResourceAsStream(String path), the path is relative to the root of the web application. This method is suitable for accessing files located within the WEB-INF directory or its subdirectories. It’s important to note that resources accessed through ServletContext are specific to the web application, meaning that each web application has its own isolated set of resources.

The ClassLoader, on the other hand, is responsible for loading classes and resources from the classpath. When you use ClassLoader.getResourceAsStream(String name), the name is the fully qualified name of the resource, relative to the root of the classpath. This method is suitable for accessing files located in directories that are included in the application server’s classpath. Resources accessed through ClassLoader can be shared between multiple web applications, which can be advantageous in certain scenarios. However, it’s important to manage classpath dependencies carefully to avoid conflicts between different applications. See Baeldung’s article on ClassLoaders in Java for a more in-depth explanation.

Featured Snippet:

To summarize, using ServletContext is ideal for application-specific configuration files located within the WEB-INF directory, providing security and isolation. Conversely, ClassLoader is suitable for shared configuration files located on the application server’s classpath, enabling resource sharing across multiple web applications. The key is to choose the method that best aligns with your application’s deployment strategy and security requirements.

Securing Configuration Resource Files

Security is paramount when dealing with configuration resource files, especially those containing sensitive information such as database passwords or API keys. It’s essential to implement appropriate security measures to protect these files from unauthorized access. Failing to do so can expose your application to serious security vulnerabilities. Always encrypt sensitive data and use secure storage mechanisms.

One of the most important security measures is to ensure that configuration files are not directly accessible to web browsers. This can be achieved by placing the files within the WEB-INF directory, as this directory is protected by the servlet container. Another important measure is to restrict access to the configuration files on the server’s file system. This can be done by setting appropriate file permissions to prevent unauthorized users from reading or modifying the files. It is advisable to routinely audit your configurations to make sure security protocols are up to date.

Furthermore, consider encrypting sensitive data within the configuration files. For example, you can encrypt database passwords or API keys using a strong encryption algorithm and store the encrypted values in the configuration files. Your application can then decrypt the values at runtime when needed. This adds an extra layer of security, making it more difficult for attackers to obtain sensitive information even if they manage to access the configuration files. One approach is to use Java Cryptography Extension (JCE) to encrypt and decrypt data. Check out additional security practices here to further enhance your application’s security posture.

  • Best Practices Recap
    • Store configuration files in external files, not hardcoded in code.
    • Secure configuration files by restricting access and encrypting sensitive data.
  • Key Methods for Accessing Resources
    • ServletContext.getResourceAsStream(String path) for web application-specific resources.
    • ClassLoader.getResourceAsStream(String name) for shared resources on the classpath.
  1. Steps to Read a Properties File:
  2. Place the properties file in the WEB-INF/config directory.
  3. Obtain the ServletContext instance.
  4. Use ServletContext.getResourceAsStream(“WEB-INF/config/myconfig.properties”) to get an InputStream.
  5. Load the properties from the InputStream using Properties.load(InputStream).

FAQ: Configuration Resource Files in Servlet Applications

**Q: What is the best location for configuration files in a servlet application?**
A: The WEB-INF directory or the application server's classpath are generally recommended. WEB-INF offers security, while the classpath allows for shared configurations.
**Q: How do I prevent direct access to configuration files?**
A: Place configuration files within the WEB-INF directory, which is protected by the servlet container.
**Q: Should I encrypt sensitive data in configuration files?**
A: Yes, encrypting sensitive data such as passwords and API keys is highly recommended to protect against unauthorized access.
**Q: What libraries can I use to read complex configuration files?**
A: Libraries like Apache Commons Configuration and Jackson provide advanced features for reading and managing complex configuration files.
The proper management of configuration resource files is vital for any robust servlet-based application. By understanding the best practices for placement, reading, and securing these files, you can ensure that your application is not only functional but also maintainable and secure. You've learned where to place your files for security, how to read them efficiently, and what tools are available to manage complex configurations. Now, take these insights and apply them to your projects. Start by reviewing your current configuration management strategy, identifying areas for improvement, and implementing the techniques discussed in this article. By doing so, you'll be well on your way to building more reliable and secure servlet-based applications. You can explore other articles about Servlet best practices and application security to further enhance your knowledge and skills. Also, read up on OAuth 2.0 for API authentication for additional security measures. **Question & Answer :** In my web application I have to send email to set of predefined users like `[email protected]`, so I wish to add that to a `.properties` file and access it when required. Is this a correct procedure, if so then where should I place this file? I am using Netbeans IDE which is having two separate folders for source and JSP files.

It’s your choice. There are basically three ways in a Java web application archive (WAR):


  1. Put it in classpath ======================

So that you can load it by ClassLoader#getResourceAsStream() with a classpath-relative path:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream input = classLoader.getResourceAsStream("foo.properties"); // ... Properties properties = new Properties(); properties.load(input); 

Here foo.properties is supposed to be placed in one of the roots which are covered by the default classpath of a webapp, e.g. webapp’s /WEB-INF/lib and /WEB-INF/classes, server’s /lib, or JDK/JRE’s /lib. If the propertiesfile is webapp-specific, best is to place it in /WEB-INF/classes. If you’re developing a standard WAR project in an IDE, drop it in src folder (the project’s source folder). If you’re using a Maven project, drop it in /main/resources folder.

You can alternatively also put it somewhere outside the default classpath and add its path to the classpath of the appserver. In for example Tomcat you can configure it as shared.loader property of Tomcat/conf/catalina.properties.

If you have placed the foo.properties it in a Java package structure like com.example, then you need to load it as below

ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); InputStream input = classLoader.getResourceAsStream("com/example/foo.properties"); // ... 

Note that this path of a context class loader should not start with a /. Only when you’re using a “relative” class loader such as SomeClass.class.getClassLoader(), then you indeed need to start it with a /.

ClassLoader classLoader = getClass().getClassLoader(); InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties"); // ... 

However, the visibility of the properties file depends then on the class loader in question. It’s only visible to the same class loader as the one which loaded the class. So, if the class is loaded by e.g. server common classloader instead of webapp classloader, and the properties file is inside webapp itself, then it’s invisible. The context class loader is your safest bet so you can place the properties file “everywhere” in the classpath and/or you intend to be able to override a server-provided one from the webapp on.


  1. Put it in webcontent =======================

So that you can load it by ServletContext#getResourceAsStream() with a webcontent-relative path:

InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties"); // ... 

Note that I have demonstrated to place the file in /WEB-INF folder, otherwise it would have been public accessible by any webbrowser. Also note that the ServletContext is in any HttpServlet class just accessible by the inherited GenericServlet#getServletContext() and in Filter by FilterConfig#getServletContext(). In case you’re not in a servlet class, it’s usually just injectable via @Inject.


  1. Put it in local disk file system ===================================

So that you can load it the usual java.io way with an absolute local disk file system path:

InputStream input = new FileInputStream("/absolute/path/to/foo.properties"); // ... 

Note the importance of using an absolute path. Relative local disk file system paths are an absolute no-go in a Java EE web application. See also the first “See also” link below.


Which to choose?

Just weigh the advantages/disadvantages in your own opinion of maintainability.

If the properties files are “static” and never needs to change during runtime, then you could keep them in the WAR.

If you prefer being able to edit properties files from outside the web application without the need to rebuild and redeploy the WAR every time, then put it in the classpath outside the project (if necessary add the directory to the classpath).

If you prefer being able to edit properties files programmatically from inside the web application using Properties#store() method, put it outside the web application. As the Properties#store() requires a Writer, you can’t go around using a disk file system path. That path can in turn be passed to the web application as a VM argument or system property. As a precaution, never use getRealPath(). All changes in deploy folder will get lost on a redeploy for the simple reason that the changes are not reflected back in original WAR file.

See also: