当前位置: 首页 > 知识库问答 >
问题:

Spring靴属性 Yml/具有列表结构的属性

齐琦
2023-03-14

我已经在stackoverflow和网络上寻找解决方案。我没有见过有效的解决方案,因为可能没有一个帖子完全符合我的用例,它包含文件中的列表和对象结构。

这里有一个例子作为yaml

teddy.list:
    -
      name: Red
      price: Five
    -
      name: Blue
      price: One
    -
      name: Yellow
      price: Two
    -
      name: Green
      price: Three

这是与属性文件相同的示例

teddy.list[0].name=Red
teddy.list[0].price=Five
teddy.list[1].name=Blue
teddy.list[1].price=One
teddy.list[2].name=Yellow
teddy.list[2].price=Two
teddy.list[3].name=Green
teddy.list[3].price=Three

我希望能够向我的应用程序提供 teddy.yml 或 teddy.properties 文件以进行配置。

这是我的课程:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource(name = "props", value = "classpath:teddy.yml", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {

    @Autowired
    Environment env;

    @Value("${teddy.list}")
    private TeddyBear[] teddyBears;

    public TeddyBear[] getTeddyBears() {
        return teddyBears;
    }

    public void setTeddyBears(TeddyBear[] teddyBears) {
        this.teddyBears = teddyBears;
    }

    public static class TeddyBear {
        private String name;
        private String price;

        public TeddyBear() {

        }

        public TeddyBear(String name, String price) {
            this.name = name;
            this.price = price;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPrice() {
            return price;
        }

        public void setPrice(String price) {
            this.price = price;
        }
    }
}

我已经尝试了这种设置,使用环境来尝试访问属性,删除前缀,声明一个“PropertySourcesPlaceholderConfigurer”的bean。

对于当前代码,spring抛出了一个IllegalStateException,因为它无法将java.lang.string转换为我的TeddyBear类。

共有3个答案

赖明煦
2023-03-14

由于您使用的是ConfigurationProperties注释,而不是

@Value("${teddy.list}")
private TeddyBear[] teddyBears;

你可以直接做

private List<TeddyBear> list;

不需要< code>@Value批注。

此外,变量名必须是< code>list,因为这是您提供给yml的内容。

燕禄
2023-03-14

小心。根据Spring版本,上面的代码可能不起作用!

这可能!

private List<TeddyBear> list = new ArrayList<>;

public List<TeddyBear> getList() {
  return list;
}

诀窍是Spring因子分解调用getList()并将TeddyBears添加到新的ArrayList中。在空指针上,它没有任何可添加的内容。抛弃获取者。未使用。

您只需要进一步:

@Autowired
TeddyBearConfig teddyBearConfig;

最后一句话:如果你想让它在SpringBootTest下测试,你可能需要更多的提示。

提供一个测试应用程序作为上下文。一定有更优雅的方法,但我是这样做的:

@SpringBootTest(classes = {TestApplication.class,..

@SpringBootApplication
public class TestApplication {
   public static void main(String[] args) throws Throwable {
      SpringApplication.run(TestApplication.class, args);
  }
 }

如果是应用程序,请使用TestPropertySource。属性位于TestSources路径下:

@TestPropertySource(locations="classpath:application.properties")
通建安
2023-03-14

这应该可以。

@Configuration
@PropertySource(name = "props", value = "classpath:teddy.properties", ignoreResourceNotFound = false)
@ConfigurationProperties(prefix = "teddy")
public class TeddyBearConfig {

  private List<TeddyBear> list;

  public List<TeddyBear> getList() {
    return list;
  }

  public void setList(List<TeddyBear> list) {
    this.list = list;
  }

  public static class TeddyBear {
    private String name;
    private String price;

    public TeddyBear() {

    }

    public TeddyBear(String name, String price) {
      this.name = name;
      this.price = price;
    }

    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getPrice() {
      return price;
    }

    public void setPrice(String price) {
      this.price = price;
    }
  }
}

更新:

上面的代码适用于上面给出的属性文件。
如果你想使用yml文件,你可以这样做。但有几点。
1.你yml结构不正确,它应该是这样的

teddy:
  list:
    -
      name: Red
      price: Five
    -
      name: Blue
      price: One
    -
      name: Yellow
      price: Two
    -
      name: Green
      price: Three

2.在修复了yml结构(以及TeddyBearConfig中的文件名)之后,您将看到springboot在启动过程中没有抱怨,但TeddBearConfig中的列表变量将为空。这是springboot通过@PropertySource处理yml文件的方式中的一个错误。

3.如果您将此yml内容移动到appplication.yml并删除配置文件中的@PropertySource行,您将看到一切正常。

 类似资料:
  • 问题内容: 我正在使用JSON将一些值从外部源获取到变量中。 我有一个这样的类型,将值放入: 解组后,我可以通过以下方式访问类型: 但是如果我尝试做类似的事情: 编译器抱怨没有这样的值。 所以我的问题是,我如何根据某些条件引用我知道会存在的Go属性? 做到这一点: 但这不是很灵活,因为我将收到不同的。 问题答案: 会尽力将数据放置在最适合您的类型的位置。从技术上讲,您的第一个示例将起作用,但是即使

  • 我正在尝试从YML加载配置。如果这些是逗号分隔的值,我可以加载值,也可以加载列表。但我无法加载典型的YML列表。 配置类 工作路线。yml 不工作。yml 为什么我不能加载yml的第二个版本/我有一个语法错误? 环境:科特林,Spring2.0.0。M3

  • 问题内容: 我的ViewValue类定义如下: 在我的代码中,我需要将ViewValue实例列表转换为包含来自相应ViewValue的id字段值的列表。 我用foreach循环来做: } 有没有更好的方法来解决这个问题? 问题答案: 编辑:此答案基于以下想法:您需要对代码中其他位置的不同实体和不同属性执行类似的操作。如果您 只需 要按ID将ViewValues列表转换为Longs列表,则请坚持使用

  • 问题是我的控制器中有一个spring表单和两个具有相同属性的@ModelAttribute参数。表单的“commandName”参数设置为我的modelAttributes名称之一。令我惊讶的是,不仅将属性映射到用“commandName”指定的模型属性,还映射到第二个属性。 我还没有找到确切的解决方案,除了和我的相似之处:Spring-form多个表单具有相同的模型属性名称属性 但在我的例子中,

  • 问题内容: 我正在尝试读取文件,并用逗号在每行中拆分一个单元格,然后仅显示包含有关纬度和经度信息的第一和第二个单元格。这是文件: 时间, 纬度,经度 ,类型2015-03-20T10:20:35.890Z, 38.8221664,-122.7649994 ,地震 2015-03-20T10 :18:13.070Z, 33.2073333,-116.6891667 ,地震 2015-03-20T10

  • 我试图分裂链接的图像是什么错在我的代码