0

read this article on SO, and had some clarifying questions.

I put my config.properties under src/main/resources

In spring-servlet.xml config file

I added the following:

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

In my business layer, I am trying to access it via

@Value("${upload.file.path}")
private String uploadFilePath;

Eclipse shows error:

The attribute value is undefined for the annotation type Value

Can i not access the property in the business layer or are property files only read in the controller?

UPDATE:: src/main/java/com.companyname.controllers/homecontroller.java

public String home(Locale locale, Model model) {
    MyServiceObject myObj = new MyServiceObject();
    System.out.println("Property from my service object: = " + myObj.PropertyValue());

    if(myObj.PerformService())
    {
      ///
    }
}

src/main/java/com.companyname.services/MyService.java

public class MyServiceObject {

    @Value("${db.server.ip}")
    private String _dbServerIP;


    public String PropertyValue() {

        return _dbServerIPaseURL;
    }



}

Another site where I found the explanation

Community
  • 1
  • 1
user1361914
  • 411
  • 1
  • 14
  • 26

2 Answers2

0

Please check that you import Value from org.springframework.beans.factory.annotation package:

import org.springframework.beans.factory.annotation.Value;

also the property placeholder must be declared in the respective context configuration file, in case of controller it's likely Spring dispatcher servlet configuration file.

update You are confusing property-placeholder that post processes bean values, that contain dollar symbol ${<property name>} with Spring expression language container extension that process values containing a hash symbol #{<Spring expression language expression>}, in the link you have shown the latter approach is used.

regarding the instantiation of MyServiceObject myObj If you want the object to be managed by Spring you should delegate its creation to the container:

  • if MyServiceObject is a stateless service then it's a singleton with the singleton bean scope, you should register it in your application context, for example with the following xml configuration:

    <bean class="my.package.MyServiceObject"/>
    

    and inject it to your controller:

    private MyServiceObject myServiceObject;
    @Autowired 
    public void setMyServiceObject(MyServiceObject myServiceObject){
       this.myServiceObject = myServiceObject;
    }
    
  • if many instances of MyServiceObject are required, you can declare it as a bean with some other (non-singleton) bean scope (prototype, or request, for example). However, as there's only one instance of the controller, you can't merely let the Spring container to autowire MyServiceObject instance to the controller field, because there will be only one field and many instances of MyServiceObject class. You can read about the different approaches(for the different bean scopes) for resolving this issue in the respective section of the documentation.

Boris Treukhov
  • 17,493
  • 9
  • 70
  • 91
  • if it is not in the controller, where would the respective context config file be located? – user1361914 Nov 16 '12 at 17:14
  • Did changing imports in the controller java file solved the problem? In spring MVC you typically have IoC containers and at least two configuration files http://stackoverflow.com/questions/11708967/what-is-the-difference-between-applicationcontext-and-webapplicationcontext-in-s/11709272#11709272 – Boris Treukhov Nov 16 '12 at 17:16
  • If it's a dao or a service(not controller) than the it will be the root web app context configuration file I believe. Assuming that the DAOs are instantiated in the root web app context, of course. – Boris Treukhov Nov 16 '12 at 17:17
  • theory http://stackoverflow.com/questions/11890544/spring-value-annotation-in-controller-class-not-evaluating-to-value-inside-pro – Boris Treukhov Nov 16 '12 at 17:23
  • Adding the import did not solve the problem. The compile error went away, however it does not seem to read from the property file. – user1361914 Nov 19 '12 at 15:48
  • @user1361914 can you give more information about the business object? how is it instantiated - the class source and the bean declaration – Boris Treukhov Nov 19 '12 at 15:52
  • Boris Treukhov: Thanks for the answer. Just getting hands dirty on spring and playing with a test project that I have converting from .net to spring mvc – user1361914 Nov 19 '12 at 19:07
  • @user1361914 Then pls accept this as the answer, or the question will remain in the SO list of unanswered ones. :) – Boris Treukhov Nov 19 '12 at 21:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19787/discussion-between-user1361914-and-boris-treukhov) – user1361914 Nov 20 '12 at 00:35
0

Here is a method that allows us to fetch whatever values are needed from a property file. This can be in Java code (Controller class) or in a JSP.

  • Create a property file WEB-INF/classes/messageSource.properties It will be in the classpath and accessible in both controllers and JSTL. Like any property file, this one consists of a key and a value

    For example:
    hello=Hello JSTL, Hello Contoller

For the Controllers

  • Locate the xml file that you use to define your Spring beans. In my case it is named servlet-context.xml. You may need to determine that by looking in your web.xml in cases where you are using the servlet contextConfigLocation property.

  • Add a new Spring bean definition with the id="messageSource". This bean will be loaded at runtime by Spring with the property file key value pairs. Create the bean with the following properties:

    • bean id="messageSource"

    • class = org.springframework.context.support.ReloadableResourceBundleMessageSource

    • property name="basename" value="WEB-INF/classes/messageSource

  • In the bean definition file for the controller class (testController) add the messageSource as a property. This will inject the messageSource bean into the controller.

    • bean id="testController" class="com.app.springhr.TestController"
    • beans:property name="messageSource" ref="messageSource"
  • In the controller JAVA class, add the messageSource Spring Bean field and its getters and setters. Note the field type is ReloadableResourceBundleMessageSource.

    private org.springframework.context.support.ReloadableResourceBundleMessageSource messageSource;

    public org.springframework.context.support.ReloadableResourceBundleMessageSource getMessageSource() { return messageSource; }

    public void setMessageSource( org.springframework.context.support.ReloadableResourceBundleMessageSource messageSource) { this.messageSource = messageSource; }

  • In your controller code, you can now fetch any known property value from the bundle.

    String propValue = getMessageSource().getMessage("hello", objArray, null);

Using JSTL

Since the property file messageSource.properties is in the classpath, JSTL will be able to find it and fetch the value for the given key.

  • Add the import of the fmt taglib

    • taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"

    • Use the fmt:tag in the JSP to fetch a value from the property file.

      Sorry about the pseudo syntax, this editor doesn't seem to render any XML.

      fmt:bundle basename="messageSource"

      fmt:message key="hello"

    • Hope this helps others