在 Kotlin 中创建 Spring 的 ParameterizedTypeReference 实例

Posted

技术标签:

【中文标题】在 Kotlin 中创建 Spring 的 ParameterizedTypeReference 实例【英文标题】:Create instance of Spring´s ParameterizedTypeReference in Kotlin 【发布时间】:2019-03-06 00:13:46 【问题描述】:

我正在尝试学习 Kotlin,并测试它如何与 Spring Boot 一起使用。我的应用程序使用 mongo 数据库来存储数据,并且我有一个 Jersey 资源来检索数据。我正在使用spring-boot-testRestTestTemplate 对其进行测试。

RestTestTemplate 有一个exchange 方法,它采用ParameterizedTypeReference。这个类有一个受保护的构造函数。所以我设法从 Kotlin 中使用它的唯一方法是这样的:

class ListOfPeople : ParameterizedTypeReference<List<Person>>()

这是我的测试方法:

@Test
fun `get list of people`() 
    // create testdata
    datastore.save(Person(firstname = "test1", lastname = "lastname1"))
    datastore.save(Person(firstname = "test2", lastname = "lastname2"))
    datastore.save(Person(firstname = "test3", lastname = "lastname2"))
    datastore.save(Person(firstname = "test4", lastname = "lastname2"))

    val requestEntity = RequestEntity<Any>(HttpMethod.GET, URI.create("/person"))

    // create typereference for response de-serialization
    class ListOfPeople : ParameterizedTypeReference<List<Person>>() // can this be done inline in the exchange method?
    val responseEntity : ResponseEntity<List<Person>> = restTemplate.exchange(requestEntity, ListOfPeople())

    assertNotNull(responseEntity)
    assertEquals(200, responseEntity.statusCodeValue)
    assertTrue( responseEntity.body.size >= 4 )

    responseEntity.body.forEach  person ->
        println("Found person: [$person.firstname $person.lastname] " +
                ", born [$person.birthdate]")
    

这是执行此操作的正确(或唯一)方法,还是有更好的方法?

如果有帮助,这里是整个测试的链接:testclass on github

【问题讨论】:

kotlinlang.org/docs/reference/… 谢谢!我今天早些时候读过它,但无法让它发挥作用。现在试了一下,这个:restTemplate.exchange(requestEntity, object: ParameterizedTypeReference> () ) 工作。谢谢! 【参考方案1】:

虽然使用对象表达式的答案是正确的,并且直接等同于您在 Java 中的做法,但如果您需要许多 ParameterizedTypeReferences,具体类型参数允许您简化它:

inline fun <reified T> typeReference() = object : ParameterizedTypeReference<T>() 

// called as
restTemplate.exchange(requestEntity, typeReference<List<Person>>())

当编译器看到 typeReference&lt;SomeType&gt; 调用时,它被定义替换,因此结果与您编写 object : ParameterizedTypeReference&lt;SomeType&gt;() 时相同。

【讨论】:

谢谢。我接受这个答案,因为我认为它更好。当我需要多个用例时,我绝对可以看到用例:)【参考方案2】:

感谢 JB Nizet 指出正确的文档。

val responseEntity : ResponseEntity<List<Person>> =
            restTemplate.exchange(requestEntity, 
            object: ParameterizedTypeReference<List<Person>> () )

如果我没看错,这称为对象表达式。

【讨论】:

谢谢你,但仍然不适合我。由于某种原因,内部模型(这里:Person)只是被解析为 LinkedHashMap。

以上是关于在 Kotlin 中创建 Spring 的 ParameterizedTypeReference 实例的主要内容,如果未能解决你的问题,请参考以下文章

在 Kotlin 中从 Spring 配置创建列表映射

如何在 Kotlin 常用代码中创建动态代理?

如何在 Kotlin 中创建一个打开新活动(Android Studio)的按钮?

在 kotlin 中创建泛型类的新实例的正确方法是啥?

如何计算在 Kotlin 中创建的线程数?

emre1512 在 Kotlin 中创建 Noty RelativeLayout