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

在静态编程语言中,具有嵌套集合的类不能正常工作

斜高翰
2023-03-14

有一个带有@ConfigurationProperties和@ConstructorBinding的数据类。此类包含作为集合的字段。有几个属性源(application.yml、application-dev1.yml)可以初始化集合的第一个元素。此元素的绑定无法正常工作。初始化的值仅从一个属性源提取。期望的beahavior与某些嵌套类类型的字段相同:合并来自所有属性源的值。

Kotlin 属性类

@ConfigurationProperties("tpp.test.root")
@ConstructorBinding
data class RootPropperties(
   var rootField1: String = "",
   var rootField2: String = "",
   var nested: NestedProperties = NestedProperties(),
   var nestedList: List<NestedListProperties> = listOf()
) {

data class NestedProperties(
    var nestedField1: String = "",
    var nestedField2: String = ""
)

@ConstructorBinding
data class NestedListProperties(
    var nestedListField1: String = "",
    var nestedListField2: String = ""
)
}

应用程序. yml

tpp:
  test:
    root:
      root-field1: default
      nested:
        nested-field1: default
      nested-list:
        - nested-list-field1: default

应用程序-dev1.yml

tpp:
  test:
    root:
     root-field2: dev1
     nested:
       nested-field2: dev1
     nested-list:
       - nested-list-field2: dev1

测试

@ActiveProfiles("dev1")
@SpringBootTest
internal class ConfigurationPropertiesTest {

@Autowired
lateinit var environment: Environment

@Autowired
lateinit var rootPropperties: RootPropperties

    @Test
    fun `configuration properties binding`() {
         Assertions.assertEquals("default", rootPropperties.rootField1)
         Assertions.assertEquals("dev1", rootPropperties.rootField2)

         Assertions.assertEquals("default", rootPropperties.nested.nestedField1)
         Assertions.assertEquals("dev1", rootPropperties.nested.nestedField2)

         Assertions.assertTrue(rootPropperties.nestedList.isNotEmpty())
         //org.opentest4j.AssertionFailedError:
         //Expected :default
         //Actual   :
         Assertions.assertEquals("default", rootPropperties.nestedList[0].nestedListField1)
         Assertions.assertEquals("dev1", rootPropperties.nestedList[0].nestedListField2)
    }

     @Test
     fun `environment binding`() {
        Assertions.assertEquals("default", environment.getProperty("tpp.test.root.root-field1"))
        Assertions.assertEquals("dev1", environment.getProperty("tpp.test.root.root-field2"))

        Assertions.assertEquals("default", environment.getProperty("tpp.test.root.nested.nested-field1"))
        Assertions.assertEquals("dev1", environment.getProperty("tpp.test.root.nested.nested-field2"))

        Assertions.assertEquals("default", environment.getProperty("tpp.test.root.nested-list[0].nested-list-field1"))
        Assertions.assertEquals("dev1", environment.getProperty("tpp.test.root.nested-list[0].nested-list-field2"))
    }
}

使用Root属性进行的测试失败,原因是rootPropperties.nestedList[0]. nestedListField1为空值。所有其他断言测试都成功通过。绑定仅用于收集时无法正常工作。

同时,环境测试成功通过。Environment.get属性("tpp.test.root.nested-list[0]. nested-list-field d1")解析更正后的值:“默认”。

Spring开机版本:2.6.4

共有1个答案

幸鸿轩
2023-03-14

在参考文档的这一部分中介绍

可能的解决方法是将列表切换为地图。

属性类

@ConfigurationProperties("tpp.test.root-map")
@ConstructorBinding
data class RootMapPropperties(
    var rootField1: String = "",
    var rootField2: String = "",
    var nested: NestedProperties = NestedProperties(),
    var nestedMap: Map<String, NestedMapProperties> = mapOf()
) {

    data class NestedProperties(
        var nestedField1: String = "",
        var nestedField2: String = ""
    )

    data class NestedMapProperties(
        var nestedMapField1: String = "",
        var nestedMapField2: String = ""
    )
}

应用程序. yml

tpp:
  test:    
    root-map:
      root-field1: default
      nested:
        nested-field1: default
      nested-map:
        1:
          nested-map-field1: default

应用程序-dev1.yml

tpp:    
    root-map:
      root-field2: dev1
      nested:
        nested-field2: dev1
      nested-map:
        1:
          nested-map-field2: dev1

测试

@ActiveProfiles("dev1")
@SpringBootTest
internal class ConfigurationPropertiesMapTest {

    @Autowired
    lateinit var environment: Environment

    @Autowired
    lateinit var rootPropperties: RootMapPropperties

    @Test
    fun `configuration properties binding`() {
        Assertions.assertEquals("default", rootPropperties.rootField1)
        Assertions.assertEquals("dev1", rootPropperties.rootField2)

        Assertions.assertEquals("default", rootPropperties.nested.nestedField1)
        Assertions.assertEquals("dev1", rootPropperties.nested.nestedField2)

        Assertions.assertTrue(rootPropperties.nestedMap.isNotEmpty())
        Assertions.assertEquals("default", rootPropperties.nestedMap["1"]!!.nestedMapField1)
        Assertions.assertEquals("dev1", rootPropperties.nestedMap["1"]!!.nestedMapField2)
    }
}
 类似资料:
  • 正如标题所说,我正在尝试将Java和Kotlin混合在一个项目中。这里有一个很好的例子。混合java kotlin hello world。除了kotlin在src/main/Java/somepackage/SomeClass中找不到我的任何Java类之外,所有的东西都正常工作。Java语言 这是什么原因? 我的身材。gradle看起来像这样 而不是开始尝试在更大的项目上实现这一点。我试图通过创

  • 本文向大家介绍Python 语言嵌套集合,包括了Python 语言嵌套集合的使用技巧和注意事项,需要的朋友参考一下 示例 导致: 而是使用frozenset:            

  • 我想在spring boot中使用嵌套的ConfigurationProperties,它在java中工作,但在kotlin中不工作。我的应用程序属性中有以下行: 我创建了这个结构来处理这些属性: 我添加了 插件和依赖项到我的 当我运行这段代码时,我得到了一个异常:

  • 我正在尝试使用Quarkus和Kotlin编写一个简单的反应式应用程序,其中只有一个endpoint,并使用Vertx。但这段简单的代码不起作用: 我得到这个例外: 我已经读了Quakus留档关于静态编程语言(它仍然是一种预览技术),并说了一些关于使用“@field: xxx”的事情,但是我已经尝试了很多东西,没有一个奏效。如果有人知道答案,我会非常感激。 @Inject Vertx或@Injec

  • 我试图用OkHttp和Cucumber在静态编程语言中设置一个Spring启动项目,并且在运行Cucumber任务时遇到以下错误。如何修复? 还有build gradle kts片段 我看到了这个错误https://github.com/square/okio/issues/647看起来可能是它,并修复了这个build.gradle,我如何将其翻译为kotlinbuild.gradle.kts?

  • 在Java中,程序员可以为JUnit测试用例指定预期的异常,如下所示: 在科特林我该怎么做?我尝试了两种语法变体,但都不起作用:

  • 我试图在Kotlin Vert中实现Postgres发布/订阅。x应用程序,但它似乎不起作用。以下是我尝试过的:

  • 我想知道为什么在下面的代码中没有捕捉到异常: 函数的调用方式如下: 但我还是遇到了一个导致应用程序崩溃的异常: 我想说try/catch块会捕获异常,但唉。。。 什么原因导致异常没有被捕获?我想说线程并不重要,因为我使用try/get块来处理线程中的异常。 在Laalto的回答之后,我更新了代码,如下所示(对于那些感兴趣的人):