Работа с YAML в Kotlin: библиотеки, парсинг и сериализация
YAML (YAML Ain't Markup Language) — это популярный формат сериализации данных, который широко используется для конфигурационных файлов, описания зависимостей и обмена данными. Благодаря своей читаемости и лаконичности, YAML часто предпочитают JSON или XML. В экосистеме Kotlin существует несколько зрелых библиотек для работы с YAML. В этой статье мы рассмотрим три основных подхода: SnakeYAML, Kaml и Jackson YAML.
1. SnakeYAML — классический выбор
SnakeYAML — это самая популярная Java-библиотека для парсинга YAML, которая отлично работает и в Kotlin. Она предоставляет низкоуровневый API, позволяющий читать YAML как Map, List или произвольные объекты.
Подключение (Gradle)
dependencies {
implementation("org.yaml:snakeyaml:2.2")
}
Пример: чтение простого YAML
import org.yaml.snakeyaml.Yaml
fun main() {
val yamlString = """
server:
host: "localhost"
port: 8080
ssl: false
database:
url: "jdbc:postgresql://localhost/mydb"
user: "admin"
password: "secret"
""".trimIndent()
val yaml = Yaml()
val data: Map<String, Any> = yaml.load(yamlString)
println(data)
// Вывод: {server={host=localhost, port=8080, ssl=false}, database={url=jdbc:postgresql://localhost/mydb, user=admin, password=secret}}
}
Пример: маппинг в data class
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor
data class ServerConfig(
val host: String,
val port: Int,
val ssl: Boolean
)
data class DatabaseConfig(
val url: String,
val user: String,
val password: String
)
data class AppConfig(
val server: ServerConfig,
val database: DatabaseConfig
)
fun main() {
val yamlString = """
server:
host: "localhost"
port: 8080
ssl: false
database:
url: "jdbc:postgresql://localhost/mydb"
user: "admin"
password: "secret"
""".trimIndent()
val yaml = Yaml(Constructor(AppConfig::class.java))
val config: AppConfig = yaml.load(yamlString)
println(config.server.host) // localhost
println(config.database.port) // Ошибка! port нет в DatabaseConfig
}
Важно: SnakeYAML использует рефлексию Java, поэтому data class должны иметь конструктор без параметров или использовать Constructor с указанием класса. Для вложенных структур может потребоваться ручное конфигурирование.
2. Kaml — нативная Kotlin-библиотека
Kaml (Kotlin YAML library) — это современная библиотека, написанная на Kotlin с использованием kotlinx.serialization. Она обеспечивает типобезопасность, поддержку sealed class, nullable-полей и кастомных сериализаторов.
Подключение (Gradle)
dependencies {
implementation("net.mamoe.yamlkt:yamlkt:0.13.0")
// или
implementation("com.charleskorn.kaml:kaml:0.56.0")
}
Рассмотрим Kaml от charleskorn, так как он более популярен и активно развивается.
Пример: сериализация и десериализация
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import com.charleskorn.kaml.Yaml
@Serializable
data class ServerConfig(
val host: String = "localhost",
val port: Int = 8080,
val ssl: Boolean = false
)
@Serializable
data class AppConfig(
val server: ServerConfig,
val name: String
)
fun main() {
val config = AppConfig(
server = ServerConfig(host = "example.com", port = 443, ssl = true),
name = "MyApp"
)
// Сериализация в YAML
val yamlOutput: String = Yaml.default.encodeToString(config)
println(yamlOutput)
// Вывод:
// server:
// host: example.com
// port: 443
// ssl: true
// name: MyApp
// Десериализация из YAML
val yamlInput = """
server:
host: test.local
port: 9000
name: TestApp
""".trimIndent()
val parsedConfig: AppConfig = Yaml.default.decodeFromString(yamlInput)
println(parsedConfig.server.host) // test.local
}
Преимущества Kaml
- Типобезопасность — все проверяется на этапе компиляции
- Поддержка null и default values —