【问题标题】:Load spring-boot properties from json file从 json 文件加载 spring-boot 属性
【发布时间】:2017-11-17 18:00:54
【问题描述】:

是否可以从 .json 文件而不是 .yaml 或 .properties 文件加载 spring-boot 配置?从查看文档来看,这不是开箱即用的支持 - 我想知道这是否可能,如果可以,如何去做?

【问题讨论】:

  • 为什么要从 json 加载配置?
  • 它是一个框架,它是 spring-boot 的包装器。框架的用户更喜欢使用 json 作为配置文件。
  • 在 spring boot 加载 yaml 之前将 json 转换为 yaml。
  • 查看这篇精彩的博文。 baeldung.com/spring-boot-json-properties

标签: java json spring spring-boot properties


【解决方案1】:

如上所述 in docson GitHub

YAML 是 JSON 的超集

所以你可以在你的 Spring Boot 项目中创建以下类:

public class JsonPropertySourceLoader extends YamlPropertySourceLoader {
    @Override
    public String[] getFileExtensions() {
        return new String[]{"json"};
    }
}

然后创建一个文件:

/src/main/resources/META-INF/spring.factories 内容如下:

org.springframework.boot.env.PropertySourceLoader=\
io.myapp.JsonPropertySourceLoader

您的 Spring 应用程序已准备好从 application.json 加载 JSON 配置。优先级是:.properties -> .yaml -> .json

如果您有多个应用程序,您可以使用共享的 PropertySourceLoaderspring.factories 文件创建一个 jar,以便将其包含到您需要的任何项目中。

【讨论】:

    【解决方案2】:

    可以在命令行中使用环境变量提供 SPRING_APPLICATION_JSON 属性。例如,您可以在 UN*X shell 中使用以下行:

    $ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar

    在前面的示例中,您最终会在 Spring 环境中使用 acme.name=test。您还可以在 System 属性中将 JSON 作为 spring.application.json 提供,如下例所示:

    $ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar

    您还可以使用命令行参数提供 JSON,如下例所示:

    $ java -jar myapp.jar --spring.application.json='{"name":"test"}'

    您还可以将 JSON 作为 JNDI 变量提供,如下所示:

    java:comp/env/spring.application.json.

    参考文档:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

    【讨论】:

      【解决方案3】:

      spring boot方式:

      @EnableAutoConfiguration
      @Configuration
      @PropertySource(value = { "classpath:/properties/config.default.json" }, factory=SpringBootTest.JsonLoader.class )
      public class SpringBootTest extends SpringBootServletInitializer {
      
          @Bean
          public Object test(Environment e) {
              System.out.println(e.getProperty("test"));
              return new Object();
          }
      
      
          public static void main(String[] args) {
              SpringApplication.run(SpringBootTest.class);
          }
      
          public static class JsonLoader implements PropertySourceFactory {
      
              @Override
              public org.springframework.core.env.PropertySource<?> createPropertySource(String name,
                      EncodedResource resource) throws IOException {
                  Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class);
                  return new MapPropertySource("json-source", readValue);
              }
      
          }
      }
      

      定义您自己的PropertySourceFactory 并通过@PropertySource 注释将其挂钩。阅读资源,设置属性,在任何地方使用它们。

      唯一的问题是,如何翻译嵌套属性。 Spring 的方法(顺便说一下,您也可以将 Json 定义为属性的变量,请参阅:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html) 就是这样翻译嵌套属性:

      {"test": { "test2" : "x" } }
      

      变成:

      test.test2.x
      

      希望对你有帮助,

      阿图尔

      【讨论】:

        【解决方案4】:

        两步

        public String asYaml(String jsonString) throws JsonProcessingException, IOException {
            // parse JSON
            JsonNode jsonNodeTree = new ObjectMapper().readTree(jsonString);
            // save it as YAML
            String jsonAsYaml = new YAMLMapper().writeValueAsString(jsonNodeTree);
            return jsonAsYaml;
        }
        

        来自the post

        public class YamlFileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
          @Override
          public void initialize(ConfigurableApplicationContext applicationContext) {
            try {
                Resource resource = applicationContext.getResource("classpath:file.yml");
                YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
                PropertySource<?> yamlTestProperties = yamlTestProperties = sourceLoader.load("yamlTestProperties", resource, null);
                applicationContext.getEnvironment().getPropertySources().addFirst(yamlTestProperties);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
          }
        }
        

        来自the post

        所以你可以将两者结合起来。将您的 json 作为资源加载并转换为 yaml,然后将所有找到的属性添加到 Environment

        【讨论】:

          猜你喜欢
          • 2019-03-30
          • 2020-04-14
          • 2020-06-05
          • 1970-01-01
          • 2019-03-04
          • 2021-09-23
          • 2014-12-21
          • 2018-03-28
          • 1970-01-01
          相关资源
          最近更新 更多