Reputation: 1135
I'm trying to implement a basic function for handling external API calls :
inline fun <reified T> get(url: String): T? {
try {
val restTemplate = RestTemplate()
val response = restTemplate.exchange<Any>(
url,
HttpMethod.GET,
headersForRestTemplate,
T::class)
return response.getBody() as T
} catch (e: Exception) {
log.info("Exception ::" + e.message)
throw ServiceException(e)
}
}
The way I'm calling it is pretty straightforward :
api.get<SWObject>(Utils.SW_API)
When trying to execute that code, I get a cast exception :
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to jp.co.xx.demo.models.SWObject
Object returned is not an instance of the SWObject
class but a LinkedHashMap
. I'm still struggling with reified
or inline
keyword, sorry if my implementation doesn't follow the best practices.
Upvotes: 1
Views: 478
Reputation: 3232
Use T::class.java
instead of T::class
in the exchange
method and remove the explicit type argument Any
from the exchange
method invocation as it became unnecessary. You also don't need to cast the response body to T
.
inline fun <reified T> get(url: String): T? {
try {
val restTemplate = RestTemplate()
val response = restTemplate.exchange(
url,
HttpMethod.GET,
headersForRestTemplate,
T::class.java
)
return response.getBody()
} catch (e: Exception) {
log.info("Exception ::" + e.message)
throw ServiceException(e)
}
}
Object::class
returns a Kotlin class (KClass
) while Object::class.java
returns a Java class (Class
) and is equivalent to Java's Object.class
. Note that KClass
is not the same as Class
.
The exchange
method just expects its responseType
argument to be the type of Class
(or ParametrizedTypeReference
but that's not the case for that).
Upvotes: 2