Сериализация — это процесс преобразования объекта или структуры данных в последовательный формат, пригодный для передачи по сети или сохранения в файл. Обратный процесс, десериализация, восстанавливает данные в исходное состояние. По данным MDN Web Docs, сериализация необходима для любого межпроцессного взаимодействия. Сериализация лежит в основе REST API, кеширования и обмена данными между компонентами приложения.
Главное
Сериализация — это процесс преобразования объекта, находящегося в оперативной памяти, в линейную последовательность байт или символов, которую можно передать по сети, сохранить в файл или передать другому процессу. Без сериализации невозможна сетевая коммуникация, хранение состояния и межпроцессное взаимодействие.
Сериализация включает два встречных процесса. Прямой процесс (сериализация) упаковывает данные в формат для передачи. Обратный процесс (десериализация) восстанавливает данные обратно в объект. Десериализация критична для безопасности: некорректные входные данные могут привести к уязвимостям в приложении.
В разработке мобильных приложений сериализация используется повсеместно: отправка запросов на сервер и обработка ответов, сохранение состояния приложения при повороте экрана, кеширование данных на диске и передача данных между экранами через Intent (Android) или Segue (iOS).
Форматы сериализации делятся на текстовые и бинарные. Текстовые форматы (JSON, XML) читаемы человеком и не требуют инструментов для просмотра. Бинарные форматы (Protobuf, FlatBuffers, MessagePack) компактнее и быстрее, но нечитаемы без десериализации. Выбор формата — компромисс между производительностью и удобством отладки.
Помимо JSON, XML и Protobuf, существуют специализированные форматы: FlatBuffers от Google для игр и AR, MessagePack — компактный бинарный аналог JSON, Avro от Apache для больших данных в Kafka, YAML — конфигурационный формат с поддержкой комментариев.
| Формат | Тип | Схема | Размер | Скорость |
|---|---|---|---|---|
| JSON | Текстовый | Опционально | Средний | Средняя |
| XML | Текстовый | XSD | Большой | Низкая |
| Protobuf | Бинарный | Обязательно | Малый | Высокая |
| FlatBuffers | Бинарный | Обязательно | Малый | Максимальная |
| MessagePack | Бинарный | Нет | Малый | Высокая |
| Avro | Бинарный | JSON Schema | Малый | Высокая |
Сериализация на мобильных платформах имеет свою специфику: ограниченный трафик, слабые процессоры и необходимость сохранения состояния при поворотах экрана. На Android используются Gson, Moshi, Kotlinx Serialization. На iOS — Codable, JSONSerialization, PropertyListEncoder. Правильный выбор библиотеки критически влияет на производительность приложения.
Kotlinx Serialization — современная библиотека от JetBrains для Kotlin Multiplatform Mobile. Она поддерживает JSON, Protobuf, CBOR и пользовательские форматы. Генерация кода происходит на этапе компиляции через плагин Kotlin Serialization, что обеспечивает высокую производительность без использования рефлексии.
Библиотека Kotlinx Serialization использует аннотацию @Serializable для классов и компиляторный плагин для генерации сериализаторов. Это обеспечивает высокую производительность и типобезопасность. Формат по умолчанию — JSON, но поддерживаются и другие форматы через дополнительные модули.
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
@Serializable
data class Project(
val id: Int,
val name: String,
val platforms: List<String>,
val active: Boolean
)
val json = Json {
prettyPrint = true
ignoreUnknownKeys = true
encodeDefaults = true
}
fun main() {
val project = Project(1, "MobileApp",
listOf("Android", "iOS"), true)
// Сериализация
val jsonString = json.encodeToString(project)
// Десериализация
val restored = json.decodeFromString<Project>(jsonString)
}
Протокол Codable — встроенный механизм сериализации в Swift. Он объединяет протоколы Encodable (сериализация) и Decodable (десериализация). JSONEncoder и JSONDecoder автоматически обрабатывают вложенные структуры, массивы, опциональные значения и кастомные ключи через CodingKeys.
import Foundation
struct AppConfig: Codable {
let appName: String
let version: String
let features: [String]
let isProduction: Bool
}
let config = AppConfig(
appName: "MyApp",
version: "2.1.0",
features: ["push", "analytics", "offline"],
isProduction: true
)
let encoder = JSONEncoder()
encoder.outputFormatting = [.prettyPrinted, .sortedKeys]
guard let data = try? encoder.encode(config) else { return }
let jsonString = String(data: data, encoding: .utf8)
Производительность форматов сериализации оценивается по трём метрикам: размер сообщения, скорость сериализации и скорость десериализации. Для мобильных приложений критичны все три: размер влияет на трафик и время загрузки, скорость — на отзывчивость интерфейса и время запуска приложения.
Protobuf и FlatBuffers показывают наилучшие результаты благодаря бинарному представлению. FlatBuffers отличается тем, что не требует отдельного шага десериализации — данные читаются напрямую из бинарного буфера, что идеально для игр и AR-приложений с требованием минимальной задержки. JSON остаётся самым популярным форматом для REST API, несмотря на худшую производительность, благодаря простоте и универсальности.
| Сценарий | Рекомендуемый формат | Причина |
|---|---|---|
| REST API | JSON | Универсальность, читаемость, поддержка |
| Микросервисы | Protobuf | Компактность, скорость, gRPC |
| Игры / AR | FlatBuffers | Zero-copy, минимальная задержка |
| Big Data | Avro | Совместимость с Kafka и Hadoop |
| Конфигурация | YAML | Комментарии, читаемость |
| Android layouts | XML | Платформенный стандарт |
Практические тесты на наборе данных из 1000 объектов пользователей показывают: Protobuf создаёт сообщения размером 12 КБ (JSON — 85 КБ, XML — 120 КБ). Время сериализации: Protobuf — 2 мс, JSON — 8 мс, XML — 25 мс. Эти цифры делают бинарные форматы предпочтительными для high-load систем и мобильных приложений с ограниченным трафиком.
Примеры демонстрируют сериализацию одного и того же объекта в разных форматах. Это помогает визуально сравнить размер и читаемость. Один и тот же объект User будет сериализован в JSON, XML и Protobuf — наглядно видно, что JSON компактнее XML, а Protobuf компактнее всех и при этом нечитаем.
JSON — минималистичный синтаксис, ключи в кавычках, значения разных типов. Занимает 80 символов. Читаемость высокая, визуальная структура чёткая. Подходит для API, где важна скорость разработки и отладки.
XML — каждый элемент обёрнут в открывающий и закрывающий теги. Занимает 150 символов. Читаемость средняя, структура строгая. Подходит для документооборота и систем, требующих валидации через XSD.
Protobuf — бинарный, 32 байта для этих данных. Нечитаем — требует десериализации для просмотра. Минимальный размер делает его идеальным для высоконагруженных систем и мобильных приложений.
{
"id": 42,
"name": "IT Sectr",
"email": "team@itsectr.com",
"role": "admin",
"active": true
}
<user>
<id>42</id>
<name>IT Sectr</name>
<email>team@itsectr.com</email>
<role>admin</role>
<active>true</active>
</user>
Лучшие практики помогают избежать типовых ошибок и выбрать правильную стратегию сериализации для проекта. Следование этим рекомендациям улучшает производительность, безопасность и поддерживаемость кода.
Безопасность сериализации — критически важный аспект, особенно при десериализации данных из непроверенных источников. Атаки на десериализацию могут привести к удалённому выполнению кода (RCE), что является одной из самых опасных уязвимостей в веб- и мобильных приложениях. Наиболее известные случаи связаны с Java Serializable и Python pickle.
Protobuf и JSON имеют встроенную защиту от таких атак, так как они работают только с данными, а не с произвольными объектами. Java Serializable, напротив, может восстанавливать любые классы, доступные в classpath, что делает его опасным для приёма данных из внешних источников. На Android рекомендуется использовать Kotlinx Serialization или Moshi вместо стандартной Java Serialization.
Дополнительные меры безопасности: устанавливайте лимит на размер входных данных, валидируйте схему перед десериализацией, не доверяйте Content-Type из HTTP-заголовков, используйте allowlist для разрешённых классов. Регулярно обновляйте библиотеки сериализации, так как уязвимости в них периодически обнаруживаются и исправляются.
Часто задаваемые вопросы
Сериализация преобразует объект в последовательность байт, маршалинг (marshalling) — передаёт данные между разными адресными пространствами с сохранением типов и структуры. Маршалинг включает сериализацию как часть процесса, но также может включать кодирование ссылок и управление памятью.
FlatBuffers от Google обеспечивает максимальную скорость благодаря zero-copy десериализации — данные читаются напрямую из бинарного буфера без преобразования. Protobuf занимает второе место, JSON — третье. XML — самый медленный формат из распространённых.
Kotlinx Serialization — лучший выбор для новых проектов на Kotlin: компиляторная генерация, поддержка Kotlin Multiplatform, null safety. Moshi — хороший выбор для проектов на Java, производительнее Gson. Gson — самая простая библиотека для начала, но медленнее и использует рефлексию.
Циклические ссылки приводят к бесконечной рекурсии при сериализации. Решения: используйте ID-ссылки вместо прямых ссылок на объекты, применяйте специальные адаптеры сериализации (например, @JsonIgnore в Jackson), или перепроектируйте модель данных для устранения циклов.
Да, особенно десериализация недоверенных данных. Уязвимости десериализации могут привести к удалённому выполнению кода. Рекомендации: не десериализуйте данные из непроверенных источников, используйте allowlist классов при десериализации и валидируйте схему данных перед обработкой.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также