【问题标题】:Spring boot read array from YAML (properties) fileSpring Boot 从 YAML(属性)文件中读取数组
【发布时间】:2018-10-27 23:45:31
【问题描述】:

这是我的项目结构

- 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&lt;String&gt; 但我无法让它工作

【问题讨论】:

标签: java spring spring-boot


【解决方案1】:

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

【讨论】:

  • 我一秒钟前才找到它xD,因为它的正确答案仍然会接受它
  • 我知道这适用于 String[] 而不是 List 上的 100%
  • 经过几个小时的测试,这将在我的数组中返回一个简单的字符串!
  • 这可行,但它不是一个“干净”的解决方案,我将添加我的解决方案作为更清洁方式的第二个答案
【解决方案2】:

@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

我相信这比将字符串拆分成更小的字符串到数组更干净,希望这对某人有所帮助。

【讨论】:

  • 谢谢分享。我担心我讨厌这是必要的,但我真的很感激知道它。谢谢!
【解决方案3】:

我觉得这也是一种有效的方式:

@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();
    }
}

Bindable.setOf 如果需要 Set 而不是 List,则可以使用。

【讨论】:

    【解决方案4】:

    继续上面 Jose Martinez 的回答,如果您有一长串值以增加可读性,您可以按如下方式格式化 yaml 请参阅下面的示例。

    document:
        templates:
            filetypes: |-
              elem1,
              elem2,
              elem3,
              elem4
    
    @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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 2016-04-29
      • 2019-07-23
      • 1970-01-01
      • 2020-07-01
      • 2019-04-13
      • 2017-08-18
      相关资源
      最近更新 更多