关于Java:Spring启动从YAML(属性)文件读取数组

Spring boot read array from YAML (properties) file

这是我的项目结构

1
2
3
4
5
6
7
- src
    - main
        - java
            - mypackage
            - resources
                - config
                    application.yml

我在application.yml中有这个

1
2
3
4
5
6
7
8
9
document:
    templates:
        filetypes:
            - elem1
            - elem2
            - elem3
            - elem4
    hello:
        test:"hello"

在我的端点中,我有以下内容

1
2
3
4
5
@Value("${document.templates.filetypes}")
List<String> templatesFileTypes;

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

在任何功能中,我都可以访问System.out.println(hello)之类的东西,并且可以正常工作
但是对于fileTypes它甚至没有编译,我收到此错误:

Error creating bean with name 'configurationEndPoint': Injection of
autowired dependencies failed; nested exception is
java.lang.IllegalArgumentException: Could not resolve placeholder
'document.templates.filetypes' in value
"${document.templates.filetypes}"

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

我尝试了String[]我尝试了ArrayList,但我无法使它正常工作


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

1
2
3
document:
    templates:
        filetypes:elem1,elem2,elem3

--

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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);
    }
}


@Jose Martinez提供的另一种解决方案可以工作,但并不一定真正需要的解决方案,因为它将document.templates.filetypes读取为String,然后将其拆分为String数组。 因此,我为此添加了解决方案,

1-创建新的类FileTypesProperties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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-创建服务并注入上一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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-在您的终点,只需自动接线并致电上一个服务

1
2
3
4
5
6
7
8
9
10
11
@RestController
public class ConfigurationEndPoint {

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

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

1
2
3
4
5
6
7
document:
    templates:
        file-types:
            - elem1
            - elem2
            - elem3
            - elem4

我认为这比将String拆分成较小的字符串并拆分成数组更干净,希望这对有人有所帮助。