Spring从YAML(属性)文件读取数组

时间:2018-05-17 16:05:58

标签: java spring spring-boot

这是我的项目结构

- src
    - main
        - java
            - mypackage
            - resources
                - config
                    application.yml

我在application.yml

中有这个
document:
    templates:
        filetypes:
            - elem1
            - elem2
            - elem3
            - elem4
    hello:
        test: "hello"

在我的终端中我有以下

@Value("${document.templates.filetypes}")
List<String> templatesFileTypes;

@Value("${document.hello.test}")
String hello;

在任何功能中,我都可以访问类似System.out.println(hello)的内容,而且功能完善 但对于fileTypes,它甚至没有编译,我收到此错误:

  

创建名为'configurationEndPoint'的bean时出错:注入   自动连接依赖失败;嵌套异常是   java.lang.IllegalArgumentException:无法解析占位符   'document.templates.filetypes'的值   “$ {document.templates.filetypes}”

搜索了很多,我能找到的每个解决方案都是指向write application.yml / application.xml文件,这在我的情况下是无效的,因为我可以读取其他测试字符串而不是数组;

我试过String[]我试过ArrayList<String>但是我无法让它工作

3 个答案:

答案 0 :(得分:4)

一种方法是将元素作为分隔列表传递。通常我们使用逗号,它开箱即用于String数组。要使用List,您需要使用Spring SPEL格式设置分隔符...请参阅下面的示例。

document:
    templates:
        filetypes:elem1,elem2,elem3

-

@Value("${document.templates.filetypes:}")
private String[] array;


@Value("#{'${document.templates.filetypes}'.split(',')}")
private List<String> list;

@PostConstruct
void testList(){
    list.stream().forEach(System.out::println);
    for (String a : array) {
        System.out.println(a);
    }
}

答案 1 :(得分:0)

@Jose Martinez提供的另一个解决方案可以正常工作但不是很清楚,因为它将document.templates.filetypes作为String读取,然后将其拆分为字符串数组;因此,我正在添加我的解决方案,

1-创建新类FileTypesProperties

@Configuration
@ConfigurationProperties(prefix = "document.templates")
public class FileTypesConfig {

    private List<String> fileTypes;

    public List<String> getFileTypes() {
        return fileTypes;
    }

    public void setFileTypes(List<String> fileTypes) {
        this.fileTypes = fileTypes;
    }
}

2-创建服务并注入上一课

@Service
public class FileTypeService {
    private final List<String> fileTypes;

    @Autowired
    public FileTypeService(FileTypesConfig fileTypesConfig){
        this.fileTypes = fileTypesConfig.getFileTypes();
    }

    public List<String> getFileTypes(){
        return this.fileTypes;
    }

}

3-在您的终点只需自动装配并拨打上一个服务

@RestController
public class ConfigurationEndPoint {

    @Autowired
    FileTypeService fileTypeService;
    @GetMapping("/api/filetypes")
    @ResponseBody
    public ResponseEntity<List<String>> getDocumentTemplatesFileTypes(){
        return ResponseEntity.ok(fileTypeService.getFileTypes());
    }
}

然后您的yaml文件可以是一个真正的数组

document:
    templates:
        file-types:
            - elem1
            - elem2
            - elem3
            - elem4

我相信这比将String拆分成更小的字符串更清晰,希望这会帮助某人。

答案 2 :(得分:0)

我认为这也是一种有效的方式:

@Service
public class FileTypeService {
    private final List<String> fileTypes;

    public FileTypeService(Environment environment) {
        this.fileTypes = Binder.get(environment).bind("document.templates.filetypes", Bindable.listOf(String.class)).get();
    }
}
如果需要 Set 而不是 List,则可以使用

Bindable.setOf