I want to read a simple property file in a Spring Roo project. Seems easy, but having struggled for more than half a day, I need to ask for help.
I read many Q&A on the internet, yet I can not get it to work. I looked at Properties with Spring and Spring @PropertySource example . I'm new to Spring, so please have some patience.
My Spring version is 3.2.8
Question: How can I retrieve to test.name key value in the BaseController class.
I created a very simple Spring Roo application to illustrate what I did.
My Roo script:
// Create a new project
project --topLevelPackage com.springsource.pizzashop --projectName pizzashop
// Setup JPA persistence using EclipseLink and H2
jpa setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY
// Create domain entities
entity jpa --class ~.domain.Base
field string --fieldName name --sizeMin 2 --notNull
// Adding web layers
web mvc setup
web mvc all --package ~.web
By default in my "applicationContext.xml":
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
I did not change this file. So I did not add a bean.
I added in ..resources\\META-INF\\spring\\ folder the test.properties file, next to the database.properties which lives also there.
test.name=Google
test.url=www.google.com
I added a Java bean for the configuration file in ...\\java\\com\\springsource\\pizzashop\\domain\\PizzaProperties.java, next to the base.java class file.
package com.springsource.pizzashop.domain;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.roo.addon.javabean.RooJavaBean;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@RooJavaBean
@PropertySource("classpath:META-INF/spring/test.properties")
public class PizzaProperties {
@Value("${test.name}")
private String name;
@Value("${test.url}")
private String url;
}
Ofcourse the "PizzaProperties_Roo_JavaBean.aj" is also created having the getters and setter.
The property file is found, because when I change the name to test1.properties, I get an error.
I pushed in the Base.list method to test if I'm able to read the property file. In the method I do a System.out.println. The result is always:
In Base.list
Name = null
package com.springsource.pizzashop.web;
import com.springsource.pizzashop.domain.Base;
import com.springsource.pizzashop.domain.PizzaProperties;
import org.springframework.roo.addon.web.mvc.controller.scaffold.RooWebScaffold;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/bases")
@Controller
@RooWebScaffold(path = "bases", formBackingObject = Base.class)
public class BaseController {
@RequestMapping(produces = "text/html")
public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, @RequestParam(value = "sortFieldName", required = false) String sortFieldName, @RequestParam(value = "sortOrder", required = false) String sortOrder, Model uiModel) {
System.out.println("In Base.list");
PizzaProperties config = new PizzaProperties();
System.out.println("Name = " + config.getName());
if (page != null || size != null) {
int sizeNo = size == null ? 10 : size.intValue();
final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
uiModel.addAttribute("bases", Base.findBaseEntries(firstResult, sizeNo, sortFieldName, sortOrder));
float nrOfPages = (float) Base.countBases() / sizeNo;
uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
} else {
uiModel.addAttribute("bases", Base.findAllBases(sortFieldName, sortOrder));
}
return "bases/list";
}
}
To allow Spring to inject properties must be Spring how creates the Bean.
Try this:
Add to PizzaProperties
@Bean
annotation ( @RooJavaBean
just generates getters and setters )
...
...
@RooJavaBean
@Component
@PropertySource("classpath:META-INF/spring/test.properties")
public class PizzaProperties {
...
...
Add to BaseController
a @Autowired
property for PizzaProperties
:
...
...
@RequestMapping("/bases")
@Controller
@RooWebScaffold(path = "bases", formBackingObject = Base.class)
public class BaseController {
@Autowired
private PizzaProperties config;
@RequestMapping(produces = "text/html")
public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, @RequestParam(value = "sortFieldName", required = false) String sortFieldName, @RequestParam(value = "sortOrder", required = false) String sortOrder, Model uiModel) {
System.out.println("In Base.list");
System.out.println("Name = " + config.getName());
...
...
Note that all this is just Spring configuration, not special Spring Roo stuff.
Good luck!
jmvivo certainly set me on the right track.
A little update how I finally managed to read the property file in a Spring Roo project in a very simple, clean way.
1) In the property class only @RooJavaBean and @Component are enough! No need for @PropertySource and also no need to add @Bean. Probably because of <context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
there is no need to use the @PropertySource annotation.
2) As jmvivo indicates I had to add
@Autowired private PizzaProperties config;
to the class where I want to use the properties.
So in the end it is very clean and simple. I like to keep it KIS.
package com.springsource.pizzashop.domain;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.stereotype.Component;
@RooJavaBean
@Component
//@PropertySource("classpath:META-INF/spring/test.properties")
public class PizzaProperties {
@Value("${test.name}")
private String name;
@Value("${test.url}")
private String url;
}
and
@RequestMapping("/bases")
@Controller
@RooWebScaffold(path = "bases", formBackingObject = Base.class)
public class BaseController {
@Autowired
private PizzaProperties config;
@RequestMapping(produces = "text/html")
public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, @RequestParam(value = "sortFieldName", required = false) String sortFieldName, @RequestParam(value = "sortOrder", required = false) String sortOrder, Model uiModel) {
System.out.println("In Base.list");
System.out.println("Name = " + config.getName());
...
...
Again thanks for the help!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.