Серијализација је процес преображаја објекта или структуре података у секвенцијални формат погодан за преношење путем мреже или чување у датотеци. Обрнути процес, десеријализација, враћа податке у првобитно стање. Према MDN Web Docs, серијализација је неопходна за сваку комуникацију између процеса. Серијализација лежи у основи REST API, кеширања и размене података између компонената апликације.
Главно
Серијализација је процес преображаја објекта који се налази у оперативној меморији у линеарни низ бајтова или знакова који се може пренети путем мреже, сачувати у датотеци или проследити другом процесу. Без серијализације није могућа мрежна комуникација, чување стања и комуникација између процеса.
Серијализација укључује два супротна процеса. Директни процес (серијализација) пакује податке у формат за преношење. Обрнути процес (десеријализација) враћа податке натраге у објекат. Десеријализација је критична за безбедност: неисправни улазни подаци могу довести до рањивости у апликацији.
У развоју мобилних апликација, серијализација се користи свуда: слање захтева серверу и обрада одговора, чување стања апликације при ротацији екрана, кеширање података на диску и преношење података између екрана путем Intent (Android) или Segue (iOS).
Формати серијализације се деле на текстуалне и бинарне. Текстуални формати (JSON, XML) су чљудими људима и не захтевају алате за прегледање. Бинарни формати (Protobuf, FlatBuffers, MessagePack) су компактнији и бржи, али нису чљудици без десеријализације. Избор формата је компромис између перформанса и удобности дебагирања.
Поред JSON, XML и Protobuf, постоје специјализовани формати: FlatBuffers од Google за игрице и AR, MessagePack — компактна бинарна алтернатива JSON, Avro од Apache за велике податке у Kafki, 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 KB (JSON — 85 KB, XML — 120 KB). Време серијализације: Protobuf — 2 ms, JSON — 8 ms, XML — 25 ms. Ови бројеви чине бинарне формате пожељним за системе високог оптерећења и мобилне апликације са ограниченим саобраћајем.
Примери приказују серијализацију истог објекта у различитим форматима. Ово помаже да се визуелно упореде величина и чљудивост. Исти 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) или преградите модел података да бисте елиминисали циклусе.
Да, посебно десеријализација података из непоузданих извора. Рањивости десеријализације могу довести до даљинског извршавања кода. Препоруке: не десеријализујте податке из непозданих извора, користите белу листу класа при десеријализацији и валидирајте шему података пре обраде.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође