// build.gradle.ktsplugins { kotlin("plugin.serialization") version "2.0.0"}dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.0")}
기본 사용
import kotlinx.serialization.*import kotlinx.serialization.json.*@Serializabledata class User(val id: Long, val name: String, val email: String)val user = User(1L, "홍길동", "hong@example.com")// 직렬화 (객체 → JSON)val json = Json.encodeToString(user)// {"id":1,"name":"홍길동","email":"hong@example.com"}// 역직렬화 (JSON → 객체)val decoded = Json.decodeFromString<User>(json)
어노테이션
@SerialName — 필드명 변경
@Serializabledata class ApiResponse( @SerialName("user_id") val userId: Long, @SerialName("full_name") val fullName: String, @SerialName("created_at") val createdAt: String,)// JSON: {"user_id":1,"full_name":"홍길동","created_at":"2026-01-01"}
@Transient — 직렬화 제외
@Serializabledata class User( val id: Long, val name: String, @Transient val password: String = "", // 직렬화 제외, 기본값 필수 @Transient val cachedToken: String? = null,)
@Required — 기본값 있어도 필수
@Serializabledata class Config( @Required val version: String = "1.0", // JSON에 반드시 포함되어야 함 val debug: Boolean = false,)
@EncodeDefault — 기본값 포함/제외 제어
@Serializabledata class Settings( @EncodeDefault(EncodeDefault.Mode.ALWAYS) val theme: String = "light", // 기본값이어도 항상 포함 @EncodeDefault(EncodeDefault.Mode.NEVER) val experimental: Boolean = false, // 기본값이면 제외)
Json 설정
val json = Json { prettyPrint = true // 들여쓰기 포함 ignoreUnknownKeys = true // 모르는 키 무시 (역직렬화 시) isLenient = true // 따옴표 없는 문자열 등 허용 encodeDefaults = true // 기본값도 포함 explicitNulls = false // null 필드 제외 coerceInputValues = true // 잘못된 값을 기본값으로 allowStructuredMapKeys = true // Map 키를 객체로 허용}val pretty = json.encodeToString(user)
컬렉션 직렬화
@Serializabledata class Page<T>(val items: List<T>, val total: Int)val page = Page( items = listOf(User(1L, "Alice", "a@example.com")), total = 1,)Json.encodeToString(page)// {"items":[{"id":1,"name":"Alice","email":"a@example.com"}],"total":1}// 리스트 직렬화val users = listOf(User(1L, "Alice", "a@b.com"), User(2L, "Bob", "b@c.com"))Json.encodeToString(users)// Map 직렬화val map = mapOf("a" to 1, "b" to 2)Json.encodeToString(map) // {"a":1,"b":2}
다형성 직렬화
@Serializablesealed class Shape { @Serializable data class Circle(val radius: Double) : Shape() @Serializable data class Rectangle(val width: Double, val height: Double) : Shape()}val shape: Shape = Shape.Circle(5.0)Json.encodeToString(shape)// {"type":"Circle","radius":5.0} — type 판별자 자동 포함Json.decodeFromString<Shape>("""{"type":"Circle","radius":5.0}""")// Shape.Circle(5.0)
클래스 판별자 커스터마이징
@Serializable@JsonClassDiscriminator("kind") // 기본 "type" 대신 "kind" 사용sealed class Event { @Serializable @SerialName("click") data class Click(val x: Int, val y: Int) : Event() @Serializable @SerialName("key_press") data class KeyPress(val key: String) : Event()}