Moshi: mga pangunahing konsepto, aklatan ng JSON Kotlin at kung paano ito gumagana

May-akda: IT Sectr Nai-publish: 2026-03-15 Oras ng pagbabasa: 8 min

Ang Moshi ay isang modernong JSON library mula sa Square, na espesyal na ginawa para sa Kotlin at Android na isinasaalang-alang ang mga limitasyon ng Gson. Ito ay ganap na katugma sa null-safety ng Kotlin, bumubuo ng code sa yugto ng compilation at hindi gumagamit ng reflection, na nagpapataas ng pagganap at pagiging maaasahan. Ayon sa datos ng Square Moshi, 2024, ang Moshi ay nagbibigay ng predictable na serialization at sumusuporta sa custom na adapter para sa anumang uri ng data.

Mga Pangunahing Punto

  • Moshi — JSON library mula sa Square para sa Kotlin at Android na walang reflection
  • Kotlin adapter — built-in na suporta para sa data class, default values at null safety
  • @Json — anotasyon para sa pag-configure ng pangalan ng field at pag-balewala ng mga property
  • Mga Adapter — custom na lohika ng serialization sa pamamagitan ng @ToJson at @FromJson
  • Code generation — ang Moshi ay bumubuo ng mga adapter sa yugto ng compilation sa pamamagitan ng kapt o KSP

Ano ang Moshi

Moshi ay isang JSON library para sa JVM, Android at Kotlin Multiplatform, na ginawa ng Square (mga lumikha ng OkHttp at Retrofit). Hindi tulad ng Gson, ang Moshi ay hindi umaasa sa reflection — ang mga adapter ay nabubuo sa yugto ng compilation sa pamamagitan ng anotasyong @JsonClass(generateAdapter = true). Ginagawa nitong mas mabilis, mas ligtas at mas predictable ang Moshi sa pagtatrabaho sa mga konstruksyong tiyak sa Kotlin.

Pilosopiya at mga bentahe

Ang pangunahing pagkakaiba ng Moshi sa mga nauna ay ang pagtanggi sa reflection. Reflection ay nagpapahintulot sa Gson na gumana sa anumang klase nang walang paghahanda, ngunit ang kapalit ay mabagal na pagsisimula, kawalan ng kakayahang mag-optimize ng compiler at panganib ng mga pagkakamali sa runtime. Ang Moshi ay nangangailangan ng tahasang pagtukoy ng mga klase para sa code generation, ngunit kapalit ay nagbibigay ng bilis ng sulat-kamay na code at kumpletong kaligtasan ng uri sa yugto ng compilation.

kotlin
// Pagkonekta ng Moshi sa build.gradle
dependencies {
    implementation "com.squareup.moshi:moshi:1.15.0"
    implementation "com.squareup.moshi:moshi-kotlin:1.15.0"
    kapt "com.squareup.moshi:moshi-kotlin-codegen:1.15.0"
}

// Simpleng modelo na may code generation
@JsonClass(generateAdapter = true)
data class User(
    @Json(name = "user_id")
    val id: Int,
    val name: String,
    val email: String,
    val avatar: String? = null
)

// Paggamit
val moshi = Moshi.Builder()
    .build()
val jsonAdapter = moshi.adapter(User::class.java)

Pag-install at konfigurasyon

Upang magsimulang magtrabaho sa Moshi, kailangang magdagdag ng mga dependency sa build.gradle at mag-anotate ng mga modelo. Moshi.Builder ay nagsisilbing entry point: sa pamamagitan nito ay idinaragdag ang mga built-in na adapter para sa mga karaniwang uri, custom na adapter, at kino-configure ang pag-uugali ng library. Ang Moshi ay sumusuporta sa mga adapter para sa Date, Enum, Collection at Map na handa na, ngunit para sa mga klase ng Kotlin kinakailangan ang moshi-kotlin module. Hindi tulad ng Gson, ang Moshi ay hindi gumagamit ng reflection para sa mga klase ng Kotlin bilang default — para dito ay ikinokonekta ang KotlinJsonAdapterFactory, na nagsisilbing backup na opsyon kapag hindi inilalapat ang code generation o ang klase ay hindi na-anotahan ng @JsonClass. Ang ganitong paraan ay ginagarantiyahan na ang developer ay tahasang pumipili sa pagitan ng pagganap ng code generation at flexibility ng reflection para sa bawat partikular na klase.

Paglikha ng Moshi at pagdaragdag ng mga adapter

Pagkatapos buuin ang Moshi sa pamamagitan ng Builder, ang developer ay makakakuha ng instance ng Moshi at humihiling ng adapter para sa nais na klase. JsonAdapter ay ang sentral na bagay na nagsasagawa ng serialization sa pamamagitan ng toJson() at deserialization sa pamamagitan ng fromJson(). Awtomatikong ginagamit ng Moshi ang nabuong adapter kung ang klase ay na-anotahan ng @JsonClass(generateAdapter = true), kung hindi, inilalapat nito ang reflective KotlinJsonAdapterFactory bilang backup na opsyon. Pinagsasama ng pamamaraang ito ang bilis ng code generation sa flexibility ng reflective mechanism para sa mga proyekto ng anumang sukat at antas ng pagiging kumplikado. Ang Moshi ay angkop para sa parehong maliliit na application at malalaking proyekto ng korporasyon na may daan-daang mga modelo ng data.

kotlin
// Pag-configure ng Moshi gamit ang KotlinJsonAdapterFactory
val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .add(LocalDateAdapter())
    .build()

// Paggamit ng adapter
val adapter = moshi.adapter(User::class.java)

// Serialization
val user = User(1, "Alice", "alice@test.com")
val json = adapter.toJson(user)

// Deserialization
val jsonString = """{"user_id":2,"name":"Bob","email":"bob@test.com"}"""
val parsedUser = adapter.fromJson(jsonString)

// Pagtatrabaho sa listahan
val listAdapter = moshi.adapter(
    Types.newParameterizedType(
        List::class.java,
        User::class.java
    )
)

Mga anotasyon at adapter

Moshi ay gumagamit ng mga anotasyon para i-configure ang serialization at suportahan ang mga custom na uri. @Json(name = "...") ay nagtatakda ng JSON key para sa field. @Transient ay nagbubukod ng field mula sa serialization. @JsonClass(generateAdapter = true) ay nagpapagana ng code generation. Para sa custom na lohika, ang Moshi ay nagbibigay ng mga anotasyong @ToJson at @FromJson, na maaaring ilagay sa isang hiwalay na klase ng adapter.

@Json at mga custom adapter

Ang anotasyong @Json ay pumapalit sa @SerializedName ng Gson at gumagana nang katulad: ang field na kotlinName ay nakaugnay sa JSON key na “kotlin_name”. Para sa mga uri na hindi ma-serialize ng Moshi bilang default (hal. LocalDate), ang developer ay lumilikha ng klase na may mga pamamaraang @ToJson at @FromJson. Mga Adapter ay nirerehistro sa pamamagitan ng Moshi.Builder.add() at inilalapat nang global o para sa isang partikular na uri. Sinusuportahan ng Moshi ang sealed class at polymorphic serialization sa pamamagitan ng @JsonClass na may tahasang pagtukoy ng discriminator, na nagpapahintulot sa pagtatrabaho sa mga hierarchy ng uri sa JSON nang walang manu-manong pagsusuri ng field. Sa deserialization, ang Moshi ay binabalewala ang mga hindi kilalang key sa JSON bilang default, na tinitiyak ang backward compatibility kapag nagdaragdag ng mga bagong field sa panig ng server nang hindi binabago ang code ng kliyente. Para sa debugging, maaaring i-activate ang strict mode sa pamamagitan ng failOnUnknown, na nagtatapon ng exception kapag may nakitang hindi kilalang key.

kotlin
// Custom na adapter para sa LocalDate
class LocalDateAdapter {

    @ToJson
    fun toJson(date: LocalDate): String {
        return date.format(DateTimeFormatter.ISO_LOCAL_DATE)
    }

    @FromJson
    fun fromJson(dateString: String): LocalDate {
        return LocalDate.parse(dateString)
    }
}

// Modelo na may mga anotasyon ng Moshi
@JsonClass(generateAdapter = true)
data class Event(
    @Json(name = "event_id")
    val id: Int,

    @Json(name = "event_date")
    val date: LocalDate,

    @Transient
    val localCache: String? = null
)

// Pagrehistro ng adapter
val moshi = Moshi.Builder()
    .add(LocalDateAdapter())
    .add(KotlinJsonAdapterFactory())
    .build()

Moshi vs Gson

Ang paghahambing ng Moshi at Gson ay isang karaniwang tanong kapag pumipili ng JSON library para sa isang Android project. Moshi ay nananalo sa modernong pag-unlad ng Kotlin dahil sa code generation, null-safety at bilis. Ang Gson ay nananatiling may-katuturan para sa mga proyekto ng Java, legacy na code at mga senaryo kung saan mahalaga ang minimal na konfigurasyon. Ang pagkakaiba ay nagiging kapansin-pansin sa malalaking volume ng data at kumplikadong mga modelo.

Pagganap at kaligtasan

Ang mga pagsubok sa pagganap ay nagpapakita na ang Moshi na may code generation ay gumagana nang 2-5 beses na mas mabilis kaysa sa Gson sa mga operasyon ng serialization at deserialization. Ang pangunahing bentahe ng Moshi ay ang tamang paghawak ng Kotlin null-safety: kung ang isang field ay wala sa JSON at sa modelo ay idineklara bilang non-null na walang default na halaga, ang Moshi ay nagtatapon ng exception sa yugto ng deserialization, na pumipigil sa mga nakatagong error.

KatangianGsonMoshi
Mekanismoreflectioncode generation / reflection
Null safetyhindi isinasaalang-alangbuong suporta sa Kotlin
Biliskatamtamanmataas
Mga default na halagahindi sinusuportahansinusuportahan
Kotlin Multiplatformhindioo
Sukat ng library~240 Kb~150 Kb

Ang pagpili sa pagitan ng Moshi at Gson ay depende sa konteksto ng proyekto. Mga bagong proyekto sa Kotlin ay nakikinabang sa Moshi dahil sa kaligtasan ng uri at pagganap. Ang Gson ay nananatiling isang makatwirang pagpipilian para sa suporta ng Java code, mga dynamic na istraktura ng JSON o kapag ang pagiging simple ng koneksyon ay mas mahalaga kaysa sa bilis. Para sa Kotlin Multiplatform, ang Moshi ay ang isa lamang sa dalawang variant na sumusuporta sa platform na ito.

Sa paglipat mula Gson patungong Moshi, ang mga pangunahing pagbabago ay may kinalaman sa mga anotasyon at adapter. Ang @SerializedName ng Gson ay pinalitan ng @Json(name = "..."), at ang custom na JsonSerializer/JsonDeserializer — ng pares na @ToJson/@FromJson. Para sa mga modelo na may mga default na halaga at nullable na field, ang Moshi ay kumikilos nang mas predictable: kung ang isang non-null na field na walang default na halaga ay wala sa JSON, ang Moshi ay nagtatapon ng JsonDataException, na pumipigil sa mga nakatagong NPE. Ang integrasyon sa Retrofit sa pamamagitan ng MoshiConverterFactory ay idinaragdag sa isang dependency at hindi nangangailangan ng pagbabago sa arkitektura ng network layer. Para sa obfuscation sa pamamagitan ng ProGuard o R8, kailangang magdagdag ng mga panuntunan para sa pagpapanatili ng mga klase na na-anotahan ng @JsonClass at mga nabuong adapter, kung hindi, masisira ang serialization sa release build. Sa pangkalahatan, ang paglipat mula Gson patungong Moshi ay makatwiran sa mga bagong proyekto ng Kotlin kung saan mahalaga ang pagganap at kaligtasan ng uri.

kotlin
// Paghahambing ng serialization: Gson vs Moshi
data class Sample(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

// Gson: gumagana sa pamamagitan ng reflection
val gson = Gson()
val fromGson = gson.fromJson("""{"name":"test"}""",
    Sample::class.java)
// count = 0 (default), ngunit ang null-safety ay hindi sinusuri

// Moshi: nangangailangan ng adapter, ang null-safety ay tahas
@JsonClass(generateAdapter = true)
data class SampleMoshi(
    val name: String,
    val count: Int,
    val tags: List<String> = listOf()
)

Mga Madalas Itanong

Ano ang Moshi sa Android?

Moshi ay isang JSON library mula sa Square para sa Kotlin at Android na gumagamit ng code generation sa halip na reflection. Nagbibigay ito ng mataas na pagganap, tamang paghawak ng null-safety ng Kotlin at pagiging tugma sa Kotlin Multiplatform.

Ano ang pinagkaiba ng Moshi kaysa Gson?

Nalampasan ng Moshi ang Gson sa bilis (2-5 beses na mas mabilis dahil sa code generation), kaligtasan (isinasaalang-alang ang null anotasyon ng Kotlin) at laki (~90 Kb mas maliit). Moshi ay sumusuporta din sa Kotlin Multiplatform at mga default na halaga sa data class.

Paano gumagana ang anotasyong @JsonClass sa Moshi?

@JsonClass(generateAdapter = true) ay nag-uutos sa Moshi na bumuo ng adapter para sa klase na ito sa yugto ng compilation. Ang nabuong adapter ay nagsasagawa ng serialization nang direkta, walang reflection, na nagbibigay ng maximum na pagganap.

Paano gumawa ng custom na Moshi adapter?

Gumawa ng klase na may mga pamamaraan na na-anotahan ng @ToJson (serialization) at @FromJson (deserialization). Irehistro ang instance sa pamamagitan ng Moshi.Builder.add(). Awtomatikong hahanapin at ilalapat ng Moshi ang adapter kapag nagtatrabaho sa kaukulang uri.

Sinusuportahan ba ng Moshi ang Kotlin Multiplatform?

Oo, Moshi ay sumusuporta sa Kotlin Multiplatform mula sa bersyon 1.13.0. Ginagawa nitong ang tanging sikat na solusyon sa JSON para sa mga proyekto ng KMP, na nagpapahintulot sa paggamit ng karaniwang code ng serialization sa lahat ng target na platform.

Buod

  • Moshi — modernong JSON library mula sa Square na may code generation sa halip na reflection
  • @JsonClass — anotasyon para sa pagbuo ng adapter, nagbibigay ng bilis ng sulat-kamay na code
  • @Json — konfigurasyon ng mga JSON key, @Transient — pagbubukod ng mga field mula sa serialization
  • @ToJson at @FromJson — simpleng API para sa custom na adapter ng anumang uri
  • Null safety — isinasaalang-alang ng Moshi ang mga anotasyon ng Kotlin at nagtatapon ng exception sa hindi pagkakatugma
  • Pagganap — 2-5 beses na mas mabilis kaysa Gson sa mga operasyon ng serialization at deserialization
  • Kotlin Multiplatform — suporta sa KMP para sa unibersal na code ng serialization

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din