Loading Property values in Spring MVC
In any software application ,we are required to put certain configurable properties in the property file
And access those values in the application wherever needed.
This enables to change the property values as and when they want without changing the code.
To enable the Spring to load the properties from the property file , we need to register the below bean in spring context
- <bean id="dbProperties"
- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="location" value="classpath:db.properties" />
- </bean>
<bean id="dbProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:db.properties" /> </bean>
Loading property values in spring xml file by using placeholder resolver
In this approach , we will see how to load properties from properties file and access them in the spring xml file.
Assume that , we are creating a bean for Data Source which will have DB related properties.
We will keep them in the db.properties file as below
db.properties
- driverClassName = com.mysql.jdbc.Driver
- url = jdbc:mysql://localhost:3306/userDB
- username = kb
- password = 1234
driverClassName = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/userDB username = kb password = 1234
To access these property files in xml file, we use placeholder resolver as below
- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="${ driverClassName}" />
- <property name="url" value="${url}" />
- <property name="username" value="${username}" />
- <property name="password" value="${password}" />
- </bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${ driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </bean>
Spring will replace these placeholders like ${xxx} with the property values from the property file.
Loading property values in Java file using @Value annotation
Using @Value annotation, we can load the values from the property file in the Java file as below
- @Controller
- public class HelloController {
- @Value(“${message}”)
- Private String message;
- @RequestMapping(value="/hello",method=RequestMethod.GET)
- public String displayHelloPage(Model model){
- model.addAttribute("message", message);
- return "/hello";
- }
- }
@Controller public class HelloController { @Value(“${message}”) Private String message; @RequestMapping(value="/hello",method=RequestMethod.GET) public String displayHelloPage(Model model){ model.addAttribute("message", message); return "/hello"; } }
Lets create the project
Project structure
db.properties
- driverClassName = com.mysql.jdbc.Driver
- url = jdbc:mysql://localhost:3306/userDB
- username = kb
- password = 1234
driverClassName = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/userDB username = kb password = 1234
create the application.properties
- dateFormat=dd/MM/yyyy
dateFormat=dd/MM/yyyy
create the spring configuration file
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-3.2.xsd
- http://www.springframework.org/schema/mvc
- http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
- <context:component-scan base-package="com.kb" />
- <mvc:annotation-driven />
- <bean id="viewResolver"
- class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/pages/" />
- <property name="suffix" value=".jsp" />
- </bean>
- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
- <property name="driverClassName" value="${driverClassName}" />
- <property name="url" value="${url}" />
- <property name="username" value="${username}" />
- <property name="password" value="${password}" />
- </bean>
- <bean id="dbProperties"
- class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="locations">
- <list>
- <value>classpath:db.properties</value>
- <value>classpath:application.properties</value>
- </list>
- </property>
- </bean>
- </beans>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <context:component-scan base-package="com.kb" /> <mvc:annotation-driven /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${username}" /> <property name="password" value="${password}" /> </bean> <bean id="dbProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:db.properties</value> <value>classpath:application.properties</value> </list> </property> </bean> </beans>
We have defined 2 properties files and loading them using spring property loaded bean PropertyPlaceHolderConfigurer.
All the values referred using ${xxx} in the above xml are loaded using PropertyPlaceholderConfigurer from the properties file.
HomeController.java
- package com.kb;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- @Controller
- public class HomeController {
- @Value("${dateFormat}")
- String dateFormat;
- @RequestMapping(value="/home",method=RequestMethod.GET)
- public String getHomePage(Model model){
- model.addAttribute("dateFormat", dateFormat);
- return "/home";
- }
- }
package com.kb; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class HomeController { @Value("${dateFormat}") String dateFormat; @RequestMapping(value="/home",method=RequestMethod.GET) public String getHomePage(Model model){ model.addAttribute("dateFormat", dateFormat); return "/home"; } }
We are using @Value annotation to load the property value from the properties file.
We have passed key as an attribute for @Value annotation.
create the home.jsp
- <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
- pageEncoding="ISO-8859-1"%>
- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
- <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <title>Home</title>
- </head>
- <body>
- <div align="center">
- <h2>Date format is ${dateFormat}</h2>
- </div>
- </body>
- </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Home</title> </head> <body> <div align="center"> <h2>Date format is ${dateFormat}</h2> </div> </body> </html>
In this page, we are getting the value for dateFormat added in the model attribute.
create pom.xml
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>Spring</groupId>
- <artifactId>PropertiesLoading</artifactId>
- <packaging>war</packaging>
- <version>0.0.1-SNAPSHOT</version>
- <name>PropertiesLoading Maven Webapp</name>
- <url>http://maven.apache.org</url>
- <properties>
- <org.springframework.version>4.2.0.RELEASE</org.springframework.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>3.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${org.springframework.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${org.springframework.version}</version>
- </dependency>
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>2.5</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>javax.servlet.jsp.jstl</groupId>
- <artifactId>javax.servlet.jsp.jstl-api</artifactId>
- <version>1.2.1</version>
- </dependency>
- <dependency>
- <groupId>taglibs</groupId>
- <artifactId>standard</artifactId>
- <version>1.1.2</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>3.0.4.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.9</version>
- </dependency>
- </dependencies>
- <build>
- <finalName>PropertiesLoading</finalName>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <version>2.5.1</version>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Spring</groupId> <artifactId>PropertiesLoading</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>PropertiesLoading Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <org.springframework.version>4.2.0.RELEASE</org.springframework.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>javax.servlet.jsp.jstl-api</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>3.0.4.RELEASE</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> </dependencies> <build> <finalName>PropertiesLoading</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.5.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
create web.xml
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
- version="3.1">
- <display-name>PropertiesLoading</display-name>
- <!-- Spring MVC dispatcher servlet -->
- <servlet>
- <servlet-name>mvc-dispatcher</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>
- /WEB-INF/spring-mvc.xml,
- </param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>mvc-dispatcher</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
- </web-app>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <display-name>PropertiesLoading</display-name> <!-- Spring MVC dispatcher servlet --> <servlet> <servlet-name>mvc-dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/spring-mvc.xml, </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>mvc-dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
access below url
http://localhost:8080/PropertiesLoading/home
The value is getting picked up from the properties file.
Above value is defined inside application.properties.
Location of the property file
In Spring MVC application, we generally keep the properties file inside WEB-INF directory.
So if we want to load the property file from this location, we should define the location as below
- <property name="location" value="WEB-INF/application.properties"/>
<property name="location" value="WEB-INF/application.properties"/>
If we want to load the property file from the absolute path of the file, we can do that by defining location as below
- <property name="location" value="file:///D:/Config/application.properties" />
<property name="location" value="file:///D:/Config/application.properties" />
or
- <property name="location" value="file:D:/Config/application.properties" />
<property name="location" value="file:D:/Config/application.properties" />
Ignoring Exception thrown when resource and property key not found
By default, Spring will throw an exception if it could not find a properties file in the specified path or could not resolve a placeholder specified in the java file or xml file.
This leads to the application fails to start.
To ignore such exceptions thrown by Spring,we need to add the below additional properties to the PropertyPlaceholderConfigurer bean
- <property name="ignoreResourceNotFound" value="true" />
<property name="ignoreResourceNotFound" value="true" />
The above property signals Spring to ignore the exception when there is no property file available in the path specified.
- <property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
The above property signals Spring to ignore the exception when there is no placeholder available in the specified java or xml file.
The whole PropertyPlaceholderConfigurer bean should look like below
- <bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
- <property name="location" value="classpath:mail.properties" />
- <property name="ignoreResourceNotFound" value="true" />
- <property name="ignoreUnresolvablePlaceholders" value="true" />
- </bean>
<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:mail.properties" /> <property name="ignoreResourceNotFound" value="true" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> </bean>
Note:
When the property ignoreUnresolvablePlaceholders is set to true and a placeholder could not be resolved,Spring will inject name of the placeholder itself.