1

I have a property file with key value pairs:

key1=value1
key2=value2

Now, in my controller, I want to directly print the value of a property file (of course after loading the property file using web.xml / app-servlet.xml), like:

System.out.printl(${key1});

Is it possible to do that?

If not, I want to create an interface with all constant variable to read values from property file. How do I do it??

public interface MyConstants
{
      @Value("${key1}")
      public static final KEY_1="";
}

But as expected only empty string is assigned.

How do I solve this issue? Or, what is the best way to using property files to retrieve values? Thanks in advance...

Srikrishnan Suresh
  • 729
  • 2
  • 13
  • 31
  • see if this helps http://stackoverflow.com/questions/2704099/status-messages-on-the-spring-mvc-based-site-annotation-controller/ – krishnakumarp Jun 03 '13 at 07:05
  • Hmm in that answer is the solution that should interest you: http://stackoverflow.com/questions/1771166/access-properties-file-programatically-with-spring/6817902#6817902 – Danubian Sailor Jun 03 '13 at 07:08

3 Answers3

5

There are two reasons why having an interface for 'MyConstants' instead of a class is incorrect :

1) Spring cannot inject values to an interface which has no implementation. Simply because you wont be able instantiate the interface. Remember, Spring is just a factory and it can play only with 'things' which can be instantiated.

2) Another reason is that having an interface for storing your constants is an anti-pattern in itself. That is not what interfaces are designed for. You might want to refer to the Constant interface anti-pattern.

http://en.wikipedia.org/wiki/Constant_interface

Arun Manivannan
  • 4,213
  • 3
  • 29
  • 38
  • Thanks for the reply.. So what is the best way to use these property values say, in my different service classes.. I do not want to create interface, I do not want to store the variable in every class.. What is the solution??? – Srikrishnan Suresh Jun 03 '13 at 06:18
  • 1
    Since your constants (seeing they are Strings in your example) are just references to the actual String objects in the pool, personally, I find no fault in injecting the necessary constants in your respective classes. However, you could always replace the existing MyConstants and declare it as a class instead of an interface. – Arun Manivannan Jun 03 '13 at 06:26
4

It's possible! You need to use the util namespace in your app-servlet.xml as below:

<?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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        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/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">

    <util:properties id="props" location="classpath:yourfile.properties" />

    <!-- other -->
</beans>

And your controller is something like

@org.springframework.beans.factory.annotation.Value("#{props.key1}")
public void setFoo(String foo) {
    System.out.println("props.key1: " + foo);
}

update for another way:

You also can use namespace context

<context:property-placeholder location="classpath:yourfile.properties" />

In controller, declare a property as below

@Value("${pros.key1}")
private String foo;
Tuna
  • 2,937
  • 4
  • 37
  • 61
1

Creating a ''Constants'' class / interface is a widely used approach, but I think its a flawed approach. It creates a weird coupling where classes from different layers in your system suddenly start depending on one Constants class. It also becomes difficult to understand by looking at the constants class, as to which constant is being used by who? Not to mention the fact that it completely mocks abstraction. You suddenly have a constants class which contains information about the error message to show on the jsp, username and password of a third party api, thread pool size etc.. all in one "I know everything" class

So avoid a constant class / interface as far as possible. Look at your controllers / services, if a particular service class needs a particular configuration value that you want exposed in a property file, inject it into the class and store it as an instance level constant. This design is much cleaner from an abstraction point of view, it also helps to unit test this class easily.

In Spring, you can create a handle to a property file as follows:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations" value="classpath:my-application.properties" />       
</bean>

As the code suggests, you can mention multiple property files here. After you do this, you can reference a key from the mentioned property file, elsewhere in the context like so:

<bean id="xx" class="com.xx.SomeClass" p:imageUrl="${categories.images}"/>

The SomeClass instance here has a property called imageUrl which is now injected with the value mentioned against the categories.images key from the property file called my-application.properties

Hope this helps.

Akshay
  • 3,158
  • 24
  • 28
  • ..Though this is quite late, i.e. 3+ yrs since your comment, I was interested to know how we move such an approach to a class. What I would be nice to have is having `code``code` expressed in a Java class rather than endless xml values. – Sid Oct 04 '16 at 10:13
  • When you say in Java code, do you mean Spring Config in Java? Or do you mean in your class that is being wired? - Maybe this will answer your questions - https://www.mkyong.com/spring/spring-propertysources-example/ – Akshay Oct 04 '16 at 13:20