Create instance of Spring´s ParameterizedTypeReference in Kotlin

这一生的挚爱 提交于 2020-01-04 23:05:47

问题


I am trying to learn Kotlin, and test how it works with spring boot. My application is using a mongo database to store data and I have a Jersey resource for retrieving data. I am testing it using spring-boot-test and RestTestTemplate.

The RestTestTemplate has an exchange method which takes a ParameterizedTypeReference. This class has a protected constructor. So the only way I managed to use it from Kotlin was like this:

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

Here is my test-method:

@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}]")
    }
}

Is this the correct (or only) way to do this, or is there a better way?

If it helps, here is a link for the whole test: testclass on github


回答1:


While the answer using object expression is correct and the direct equivalent of the way you do it in Java, reified type parameters allow you to simplify it if you need many ParameterizedTypeReferences:

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

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

When the compiler sees a typeReference<SomeType> call, it's replaced by the definition, so the result is the same as if you wrote object : ParameterizedTypeReference<SomeType>() {}.




回答2:


Thanks to JB Nizet who pointed me to the correct documentation.

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

If I read correctly this is called an Object expression.



来源:https://stackoverflow.com/questions/52581729/create-instance-of-spring%c2%b4s-parameterizedtypereference-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!