UWAGA:Odpowiedź z @IRus jest poprawna, to był modyfikowany w tym samym czasie napisałem to wypełnić więcej szczegółów.
Powinieneś użyć Jackson + Kotlin module lub będziesz mieć inne problemy z deserializacją obiektów Kotlin, gdy nie masz domyślnego konstruktora.
Twoja pierwsza próbka kodu:
val dtos = mapper.readValue(json, List::class.java)
wraca się wywnioskować typ List<*>
skoro nie określił więcej informacji o typie i to jest rzeczywiście List<Map<String,Any>>
który nie jest tak naprawdę „działa OK”, ale jest nie powoduje żadnych błędów. To jest niebezpieczne, nie wpisane.
Drugi kod powinien być:
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
val mapper = jacksonObjectMapper()
// ...
val genres: List<GenreDTO> = mapper.readValue(json)
Nie trzeba niczego innego po prawej stronie przypisania, moduł Kotlin dla Jacksona będzie zreifikować generyków i stworzyć TypeReference
dla Jacksona wewnętrznie. Zwróć uwagę na import readValue
, potrzebujesz tego lub .*
dla pakietu , aby mieć funkcje rozszerzenia, które wykonują całą magię.
Nieco inna alternatywa, która również działa:
val genres = mapper.readValue<List<GenreDTO>>(json)
Nie ma powodu, aby nie używać funkcji rozszerzenia oraz dodatkowy moduł dla Jacksona. Jest mały i rozwiązuje inne problemy, które wymagałyby przeskoczenia przez obręcze w celu utworzenia domyślnego konstruktora lub użycia kilku adnotacji. Z modułem Twoja klasa może być normalną Kotlin (opcjonalnie być klasą data
):
class GenreDTO(val id: Int, val name: String)
Używałem modułu Kotlin dla Jacksona i próbowałem czegoś takiego, ale zapomniałem o imporcie. –
Mam nadzieję, że https://youtrack.jetbrains.com/issue/KT-9238 pozwoli bibliotece na opowiedzenie IDE, jakie importowanie jest dla niej ważne. –