繁体   English   中英

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

[英]Spring boot read array from YAML (properties) file

这是我的项目结构

- 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)类的东西,它完美地工作,但对于文件类型,它甚至没有编译,我收到此错误:

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

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

我试过String[]我试过ArrayList<String>但我不能让它工作

一种方法是将元素作为分隔列表传递。 通常我们使用逗号,它对字符串数组开箱即用。 要使用列表,则需要使用 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);
    }
}

@Jose Martinez 提供的另一个解决方案可以工作,但并不像需要的那样清晰,因为它将document.templates.filetypes作为字符串读取,然后将其拆分为字符串数组; 因此,我为此添加了我的解决方案,

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 拆分成更小的字符串成一个数组更干净,希望这会帮助某人。

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

@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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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