Trabalhando com JSON em Kotlin: Um Guia Completo para Parsing e Serialização
JSON (JavaScript Object Notation) continua sendo um dos formatos de troca de dados mais populares no desenvolvimento web moderno. Ao trabalhar com Kotlin, seja em uma aplicação server-side no Ktor ou em um aplicativo móvel para Android, a capacidade de analisar e serializar JSON de forma eficiente é uma habilidade essencial. Neste artigo, abordaremos três principais abordagens para trabalhar com JSON em Kotlin: usando as bibliotecas Gson, Moshi e a solução oficial da JetBrains — kotlinx.serialization.
Por que o Kotlin exige uma abordagem especial para JSON?
Kotlin é uma linguagem estaticamente tipada com recursos como segurança contra nulos (null-safety), classes de dados e propriedades padrão. Bibliotecas para trabalhar com JSON devem considerar esses recursos para garantir que o código não seja apenas funcional, mas também idiomático. Uma configuração incorreta pode levar a NullPointerException ou comportamento inesperado durante a desserialização.
1. Usando Gson para Trabalhar com JSON
Gson, do Google, é uma das bibliotecas mais antigas e difundidas. É simples de usar, mas tem algumas peculiaridades ao trabalhar com Kotlin.
Adicionando a Dependência
// build.gradle.ktsimplementation("com.google.code.gson:gson:2.10.1")Serializando um Objeto para JSON
import com.google.gson.Gson
data class User( val id: Int, val name: String, val email: String? = null)
fun main() { val user = User(1, "Ivan Petrov", "ivan@example.com") val gson = Gson() val json = gson.toJson(user) println(json) // Output: {"id":1,"name":"Ivan Petrov","email":"ivan@example.com"}}Analisando JSON em um Objeto
fun parseUser(jsonString: String): User { val gson = Gson() return gson.fromJson(jsonString, User::class.java)}
fun main() { val json = """{"id":2,"name":"Anna Smirnova","email":null}""" val user = parseUser(json) println(user.name) // Anna Smirnova}Importante: Gson usa reflexão do Java e pode não considerar a segurança contra nulos (null-safety) do Kotlin. Durante a desserialização, campos declarados como não-nulos podem receber um valor nulo, causando um erro em tempo de execução. Recomenda-se usar @JvmOverloads e construtores com valores padrão.
2. Moshi — Uma Alternativa Moderna da Square
Moshi foi criado pensando nos recursos do Kotlin e oferece melhor integração com segurança contra nulos e classes de dados.
Adicionando a Dependência
// build.gradle.ktsimplementation("com.squareup.moshi:moshi-kotlin:1.15.0")kapt("com.squareup.moshi:moshi-kotlin-codegen:1.15.0")Exemplo de Trabalho com Moshi
import com.squareup.moshi.Moshiimport com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
data class Product( val id: Int, val title: String, val price: Double, val inStock: Boolean = false)
fun main() { val moshi = Moshi.Builder() .addLast(KotlinJsonAdapterFactory()) .build()
val adapter = moshi.adapter(Product::class.java)
// Serialização val product = Product(101, "Laptop", 89999.99, true) val json = adapter.toJson(product) println(json) // {"id":101,"title":"Laptop","price":89999.99,"inStock":true}
// Desserialização val jsonString = """{"id":102,"title":"Mouse","price":2500.00}""" val parsedProduct = adapter.fromJson(jsonString) println(parsedProduct?.title) // Mouse println(parsedProduct?.inStock) // false (valor padrão)}Moshi lida automaticamente com valores padrão em classes de dados e funciona corretamente com tipos anuláveis. Para melhor desempenho, recomenda-se usar geração de código via anotação @JsonClass.