简体   繁体   中英

Spring Roo & reading property file

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM