JSON को कोटलिन में पार्स कैसे करें?


121

मुझे एक सेवा से काफी गहरी JSON ऑब्जेक्ट स्ट्रिंग मिल रही है जिसे मुझे JSON ऑब्जेक्ट के लिए पार्स करना होगा और फिर इसे कक्षाओं में मैप करना होगा।

मैं कोटलिन में ऑब्जेक्ट के लिए JSON स्ट्रिंग कैसे बदल सकता हूं?

उसके बाद संबंधित वर्गों के लिए मैपिंग, मैं जैक्सन से StdDeserializer का उपयोग कर रहा था। समस्या उस समय पैदा होती है जब ऑब्जेक्ट में ऐसे गुण होते हैं जिन्हें कक्षाओं में deserialized भी करना पड़ता था। मैं ऑब्जेक्ट मैपर प्राप्त करने में सक्षम नहीं था, कम से कम मुझे नहीं पता था कि कैसे, एक और deserializer के अंदर।

किसी भी सहायता के लिए अग्रिम रूप से धन्यवाद। अधिमानतः, मूल रूप से, मैं उन निर्भरता की संख्या को कम करने की कोशिश कर रहा हूं जिनकी मुझे आवश्यकता है, यदि उत्तर केवल JSON हेरफेर और पार्सिंग के लिए है तो यह पर्याप्त होगा।


2
मैंने जावा में विकसित नहीं किया है। यह कोई त्रुटि नहीं है जो मुझे मिल रही है। मैं अभी नहीं जानता कि कोटलिन में मूल रूप से प्रभावी पार्सिंग कैसे करें। सभी खोज हमेशा एक ढांचे की ओर ले जाती हैं। जावा में एक org.json.simple है। आईडीई के स्वत: पूर्ण सुविधाओं पर भरोसा, कोटलिन नहीं करता है।
AJ_1310

Org.json.simple पैकेज जावा के मूल निवासी नहीं है। मुझे लगता है कि यह पुस्तकालय है: github.com/fangyidong/json-simple । आप चाहे तो कोटलिन के साथ भी इसका उपयोग कर सकते हैं (हालाँकि जेसन बॉर्न ने सुझाव दिया था कि क्लेक्सन लाइब्रेरी, कोटलिन के लिए बेहतर विकल्प हो सकता है)।
30'17

Github.com/square/moshi पर एक नज़र डालें । इसके बारे में एक ब्लॉग पोस्ट है मध्यम
जेम्स मूर

जवाबों:


72

आप इस पुस्तकालय https://github.com/cbeust/klaxon का उपयोग कर सकते हैं

क्लैक्सन कोटलिन में JSON को पार्स करने के लिए एक हल्का पुस्तकालय है।


86
यहाँ लेखक, अगर आपको कोई प्रश्न / सुझाव हो तो मुझे बेझिझक ईमेल करें।
सेड्रिक बीस्ट

सही पार्सर प्राप्त करने के लिए मुझे कौन से जावा पुस्तकालय आयात करने होंगे? मैंने org.json की कोशिश की। *, लेकिन मुझे अपने ग्रेडेल सेटिंग्स में कुछ याद आ रहा है। मुझे लगता है कि Klaxon प्रलेखन बहुत कुछ मानता है (जैसे कि जावा पुस्तकालयों को जानने वाला उपयोगकर्ता)।
मकास

@CedricBeust क्या आपने वर्ग वस्तु के साथ वर्गलाइट के साथ काम करने की कोशिश की है? किसी भी अनुशंसित अभ्यास यहाँ?
राजू yourPepe

104

कोई सवाल नहीं है कि कोटलिन में पार्सिंग का भविष्य kotlinx.serialization के साथ होगा। यह कोटलिन पुस्तकालयों का हिस्सा है। यह अभी भी इनक्यूबेटर चरण में लिखने के समय पर है।

https://github.com/Kotlin/kotlinx.serialization

import kotlinx.serialization.*
import kotlinx.serialization.json.JSON

@Serializable
data class MyModel(val a: Int, @Optional val b: String = "42")

fun main(args: Array<String>) {

    // serializing objects
    val jsonData = JSON.stringify(MyModel.serializer(), MyModel(42))
    println(jsonData) // {"a": 42, "b": "42"}

    // serializing lists
    val jsonList = JSON.stringify(MyModel.serializer().list, listOf(MyModel(42)))
    println(jsonList) // [{"a": 42, "b": "42"}]

    // parsing data back
    val obj = JSON.parse(MyModel.serializer(), """{"a":42}""")
    println(obj) // MyModel(a=42, b="42")
}

3
मेरे पास जो समस्या है, वह यह है कि आप शायद ही इसे जेनेरिक के साथ उपयोग कर सकते हैं। कम से कम मुझे नहीं पता है कि ऐसा कैसे करना है। और मैं निश्चित रूप से प्रतिबिंब का उपयोग नहीं करना चाहता।
नैट्रॉनिट

3
KotlinX Serialization अभी भी प्रायोगिक चरण में है, इसलिए वे नई रिलीज़ में ब्रेकिंग परिवर्तन शुरू करते हैं। इसके अलावा, यह थ्रेड-सुरक्षित नहीं है, इसलिए यदि आपके कई थ्रेड्स Json(यह आम है) के एक ही उदाहरण का उपयोग करने का प्रयास करते हैं, तो आपका JSON दूषित हो सकता है । इसके अलावा, बग लेबल के साथ कई खुले गिटब मुद्दे हैं। इसलिए, यह अभी भी उत्पादन में उपयोग के लिए जोखिम भरा है जो मैं कहूंगा (जब तक आप संभावित मुद्दों को ठीक करने पर समय बिताने के लिए तैयार नहीं होते हैं और इसे अक्सर अपडेट करने की योजना नहीं बनाते हैं)। यह परियोजना वास्तव में विशेष रूप से कोटलिन मल्टीप्लेट प्रोजेक्ट के लिए दिलचस्प है, लेकिन यह अभी तक स्थिर नहीं है।
जवाद सादकज़ादेह

ऐसा लगता है कि पहले से ही एक परिवर्तन हो रहा है, JSON को अब Json
xjcl

यह भी एक अतिरिक्त निर्भरता आवश्यकता है, इसलिए एक गाइड के लिए लिंक का पालन करना
xjcl

34

बाहरी पुस्तकालय के बिना (Android पर)

इसे पार्स करने के लिए:

val jsonString = """
    {
       "type":"Foo",
       "data":[
          {
             "id":1,
             "title":"Hello"
          },
          {
             "id":2,
             "title":"World"
          }
       ]
    }        
"""

इन वर्गों का उपयोग करें:

import org.json.JSONObject

class Response(json: String) : JSONObject(json) {
    val type: String? = this.optString("type")
    val data = this.optJSONArray("data")
            ?.let { 0.until(it.length()).map { i -> it.optJSONObject(i) } } // returns an array of JSONObject
            ?.map { Foo(it.toString()) } // transforms each JSONObject of the array into Foo
}

class Foo(json: String) : JSONObject(json) {
    val id = this.optInt("id")
    val title: String? = this.optString("title")
}

उपयोग:

val foos = Response(jsonString)

2
इसलिए यदि इसके लिए किसी बाहरी पुस्तकालय की आवश्यकता नहीं है, तो इसका मतलब यह होना चाहिए कि org.json.JSONObject मानक पुस्तकालय का सही हिस्सा है?
still_dreaming_1

@ still_dreaming_1 हाँ यह "एपीआई स्तर 1 में जोड़ा गया" है, cf. developer.android.com/reference/org/json/JSONObject.html
frouo

मुझे लगता है कि यह एक Android बात है? मैं JVM के लिए कोटलिन या जावा मानक पुस्तकालय में इसकी तलाश कर रहा था।
still_dreaming_1

ओह हाँ बिल्कुल, मुझे खेद है कि मैं जवाब में इसका उल्लेख करना भूल गया! शायद आप उपयोग कर सकते हैं JsonObjectयदि आपका जेवीएम जावा 7 ( docs.oracle.com/javaee/7/api/javax/json/JsonObject.html ) के तहत चल रहा है ?
फूरो

ओह, मुझे वह पहले नहीं मिला, धन्यवाद! कुछ अन्य संबंधित वर्ग भी हैं जैसे कि JsonReader। ऐसा लगता है कि वे जावा ईई का हिस्सा हैं, लेकिन जावा एसई का नहीं। मैं संभवतः जावा ईई पर स्विच करूंगा।
still_dreaming_1

26

आप उपयोग कर सकते हैं Gson

उदाहरण

चरण 1

संकलन जोड़ें

compile 'com.google.code.gson:gson:2.8.2'

चरण 2

JSON को इसमें कनवर्ट करें Kotlin Bean( JsonToKotlinClass का उपयोग करें )

ऐशे ही

Json डेटा

{
"timestamp": "2018-02-13 15:45:45",
"code": "OK",
"message": "user info",
"path": "/user/info",
"data": {
    "userId": 8,
    "avatar": "/uploads/image/20180115/1516009286213053126.jpeg",
    "nickname": "",
    "gender": 0,
    "birthday": 1525968000000,
    "age": 0,
    "province": "",
    "city": "",
    "district": "",
    "workStatus": "Student",
    "userType": 0
},
"errorDetail": null
}

Kotlin Bean

class MineUserEntity {

    data class MineUserInfo(
        val timestamp: String,
        val code: String,
        val message: String,
        val path: String,
        val data: Data,
        val errorDetail: Any
    )

    data class Data(
        val userId: Int,
        val avatar: String,
        val nickname: String,
        val gender: Int,
        val birthday: Long,
        val age: Int,
        val province: String,
        val city: String,
        val district: String,
        val workStatus: String,
        val userType: Int
    )
}

चरण 3

उपयोग Gson

var gson = Gson()
var mMineUserEntity = gson?.fromJson(response, MineUserEntity.MineUserInfo::class.java)

इससे मुझे java.lang.IllegalStateException मिलती है: एक स्ट्रिंग की उम्मीद है लेकिन लाइन 1 कॉलम 700 पथ पर BEGIN_OBJECT थी
सृष्टि रॉय

आपको अपना रिटर्न डेटा पहले चेक करना चाहिए। @ SrishtiRoy
KeLiuyue

यह काम किया है, लेकिन अगर मेरे json प्रतिक्रिया "श्रेणियों" की तरह है: ["अनुशंसित"], तो?
सृष्टि रॉय

@SrishtiRoy प्रतिक्रिया अवैध JSON डेटा है। कानूनी JSON डेटा के साथ शुरू किया गया है {या[
KeLiuyue

1
Gson के साथ समस्या यह है कि यह अशक्तता की उपेक्षा करता है। एक valसंपत्ति आसानी से हो सकती है nullयदि यह JSON से गायब है। साथ ही, डिफ़ॉल्ट मानों का उपयोग नहीं किया जाता है।
user3738870

21

यकीन नहीं है कि यह वही है जो आपको चाहिए लेकिन यह है कि मैंने इसे कैसे किया।

आयात का उपयोग करना org.json.JSONObject:

    val jsonObj = JSONObject(json.substring(json.indexOf("{"), json.lastIndexOf("}") + 1))
    val foodJson = jsonObj.getJSONArray("Foods")
    for (i in 0..foodJson!!.length() - 1) {
        val categories = FoodCategoryObject()
        val name = foodJson.getJSONObject(i).getString("FoodName")
        categories.name = name
    }

यहाँ जसन का एक नमूना है:

{"खाद्य पदार्थ": [{"खाद्यनाम": "सेब", "वजन": "110"}]}


8
निर्भरता क्या है?
लुइस सोरेस 10

मैंने org.json का उपयोग किया। यहाँ लिंक दिया गया है: mvnrepository.com/artifact/org.json/json/20180813
markB

इस पद्धति के लिए यह आवश्यक है कि कक्षा में बिना किसी पैरेम्स के डिफ़ॉल्ट रूप से कंस्ट्रक्टर होना चाहिए। क्या होगा अगर डेटा वर्ग नीचे की तरह निर्माता में पैरामीटर है: data class SomeClass(val param1: Int, val param2: Int)
लीमेन्घो

@leimenghao आप इसे एक पंक्ति में कर सकते हैं: वैल श्रेणियां = SomeClass (param1 = foodJson.getJSONObject (i) .getString ("FoodName"), param2 = foodJson .getJSONObject (i) .getInt ("वजन")
markB

वास्तव में अच्छी तरह से काम करता है। बस कहने के लिए है, तो आप उपयोग कर सकते हैं for (i in 0 until foodJson!!.length()) {के बजाय for (i in 0..foodJson!!.length() - 1) {। यह ऐसा ही करता है, और यह काफी अधिक दृश्य है
अर्नमिनेर जेड

12

मैं व्यक्तिगत रूप से कोटलिन के लिए जैक्सन मॉड्यूल का उपयोग करता हूं जो आप यहां पा सकते हैं: जैकसन-मॉड्यूल-कोटलिन

implementation "com.fasterxml.jackson.module:jackson-module-kotlin:$version"

एक उदाहरण के रूप में, निर्वासन कौशल पथ के JSON को पार्स करने के लिए कोड है जो काफी भारी है (स्वरूपित होने पर 84k लाइनें):

कोटलिन कोड:

package util

import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.kotlin.*
import java.io.File

data class SkillTreeData( val characterData: Map<String, CharacterData>, val groups: Map<String, Group>, val root: Root,
                          val nodes: List<Node>, val extraImages: Map<String, ExtraImage>, val min_x: Double,
                          val min_y: Double, val max_x: Double, val max_y: Double,
                          val assets: Map<String, Map<String, String>>, val constants: Constants, val imageRoot: String,
                          val skillSprites: SkillSprites, val imageZoomLevels: List<Int> )


data class CharacterData( val base_str: Int, val base_dex: Int, val base_int: Int )

data class Group( val x: Double, val y: Double, val oo: Map<String, Boolean>?, val n: List<Int> )

data class Root( val g: Int, val o: Int, val oidx: Int, val sa: Int, val da: Int, val ia: Int, val out: List<Int> )

data class Node( val id: Int, val icon: String, val ks: Boolean, val not: Boolean, val dn: String, val m: Boolean,
                 val isJewelSocket: Boolean, val isMultipleChoice: Boolean, val isMultipleChoiceOption: Boolean,
                 val passivePointsGranted: Int, val flavourText: List<String>?, val ascendancyName: String?,
                 val isAscendancyStart: Boolean?, val reminderText: List<String>?, val spc: List<Int>, val sd: List<String>,
                 val g: Int, val o: Int, val oidx: Int, val sa: Int, val da: Int, val ia: Int, val out: List<Int> )

data class ExtraImage( val x: Double, val y: Double, val image: String )

data class Constants( val classes: Map<String, Int>, val characterAttributes: Map<String, Int>,
                      val PSSCentreInnerRadius: Int )

data class SubSpriteCoords( val x: Int, val y: Int, val w: Int, val h: Int )

data class Sprite( val filename: String, val coords: Map<String, SubSpriteCoords> )

data class SkillSprites( val normalActive: List<Sprite>, val notableActive: List<Sprite>,
                         val keystoneActive: List<Sprite>, val normalInactive: List<Sprite>,
                         val notableInactive: List<Sprite>, val keystoneInactive: List<Sprite>,
                         val mastery: List<Sprite> )

private fun convert( jsonFile: File ) {
    val mapper = jacksonObjectMapper()
    mapper.configure( DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true )

    val skillTreeData = mapper.readValue<SkillTreeData>( jsonFile )
    println("Conversion finished !")
}

fun main( args : Array<String> ) {
    val jsonFile: File = File( """rawSkilltree.json""" )
    convert( jsonFile )

JSON (प्रारूपित नहीं): http://filebin.ca/3B3reNQf3KXJ/rawSkilltree.json

आपके विवरण को देखते हुए, मेरा मानना ​​है कि यह आपकी आवश्यकताओं से मेल खाता है।



इसके अतिरिक्त, आप JSON से कोटलिन डेटा क्लास प्लगइन का उपयोग intellij में कर सकते हैं ताकि आप के लिए डेटा कक्षाएं उत्पन्न कर सकें।
ब्रूक्स डुबोइस

7

JSON को कोटलिन में बदलने के लिए http://www.json2kotlin.com/ का उपयोग करें

इसके अलावा आप एंड्रॉइड स्टूडियो प्लगइन का उपयोग कर सकते हैं। फ़ाइल> सेटिंग्स, Pluginsबाएं पेड़ में चयन करें , "ब्राउज़ रिपॉजिटरी ..." दबाएं, " JsonToKotlinClass " खोजें, इसे चुनें और हरे बटन "इंस्टॉल करें" पर क्लिक करें।

लगाना

AS पुनरारंभ होने के बाद आप इसका उपयोग कर सकते हैं। आप के साथ एक वर्ग बना सकते हैं File > New > JSON To Kotlin Class (JsonToKotlinClass)। दूसरा तरीका Alt + K को प्रेस करना है।

यहां छवि विवरण दर्ज करें

फिर आपको JSON पेस्ट करने के लिए एक डायलॉग दिखाई देगा।

2018 में मुझे package com.my.package_nameएक कक्षा की शुरुआत में जोड़ना था ।


4

सबसे पहले।

आप JSON से मैपिंग के लिए JSON से POJO क्लासेस (kotlin data class) के लिए एंड्रॉइड स्टूडियो में JSON से कोटलिन डेटा क्लास कनवर्टर प्लगइन का उपयोग कर सकते हैं। यह प्लगइन JSON के अनुसार आपके कोटलिन डेटा क्लास को एनोटेट करेगा।

तब आप JSON को कोटलिन में बदलने के लिए GSON कनवर्टर का उपयोग कर सकते हैं।

इस पूर्ण ट्यूटोरियल का पालन करें: कोटलिन एंड्रॉइड जेन्स पार्सिंग ट्यूटोरियल

अगर आप मैन्युअल रूप से json पार्स करना चाहते हैं।

val **sampleJson** = """
  [
  {
   "userId": 1,
   "id": 1,
   "title": "sunt aut facere repellat provident occaecati excepturi optio 
    reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita"
   }]
   """

JSON Array के ऊपर Parse का कोड और इंडेक्स 0 पर इसका ऑब्जेक्ट।

var jsonArray = JSONArray(sampleJson)
for (jsonIndex in 0..(jsonArray.length() - 1)) {
Log.d("JSON", jsonArray.getJSONObject(jsonIndex).getString("title"))
}

1

http://www.jsonschema2pojo.org/ हाय आप इस वेबसाइट का उपयोग कर जोंस को पूजो में बदल सकते हैं।
नियंत्रण + Alt + Shift + K

उसके बाद आप उस मॉडल क्लास को कोटलिन मॉडल क्लास में बदल सकते हैं। उपरोक्त शॉर्टकट की मदद से।


1
यह जावा में परिवर्तित हो जाएगा।
कूलमैन्ड

0

थोड़ी देर, लेकिन जो भी हो।

यदि आप JSON को जावास्क्रिप्ट में पार्स करना पसंद करते हैं जैसे कोटलिन शब्दार्थ का उपयोग करने वाले निर्माण, तो मैं JSONKraken की सलाह देता हूं , जिनमें से मैं लेखक हूं।

इस मामले पर सुझाव और राय बहुत अधिक स्पष्ट हैं!


-4

यहाँ से डेम का स्रोत डाउनलोड करें ( Android kotlin में Json पार्सिंग )

इस निर्भरता को जोड़ें:

compile 'com.squareup.okhttp3:okhttp:3.8.1'

कॉल एपीआई समारोह:

 fun run(url: String) {
    dialog.show()
    val request = Request.Builder()
            .url(url)
            .build()

    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            dialog.dismiss()

        }

        override fun onResponse(call: Call, response: Response) {
            var str_response = response.body()!!.string()
            val json_contact:JSONObject = JSONObject(str_response)

            var jsonarray_contacts:JSONArray= json_contact.getJSONArray("contacts")

            var i:Int = 0
            var size:Int = jsonarray_contacts.length()

            al_details= ArrayList();

            for (i in 0.. size-1) {
                var json_objectdetail:JSONObject=jsonarray_contacts.getJSONObject(i)


                var model:Model= Model();
                model.id=json_objectdetail.getString("id")
                model.name=json_objectdetail.getString("name")
                model.email=json_objectdetail.getString("email")
                model.address=json_objectdetail.getString("address")
                model.gender=json_objectdetail.getString("gender")

                al_details.add(model)


            }

            runOnUiThread {
                //stuff that updates ui
                val obj_adapter : CustomAdapter
                obj_adapter = CustomAdapter(applicationContext,al_details)
                lv_details.adapter=obj_adapter
            }

            dialog.dismiss()

        }

    })
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.