简体   繁体   中英

How to parse JSON manually in Kotlin?

I want to parse JSON response manually in Kotlin. Since I am getting complex JSON response which is having some common fields. For example I am getting below response.

{ 
  status: "success/false"
  apiId: 6
  message: "Error msg if any"
  .
  .   
  .    // Here comes some JSON with complex structure where some fields are
  .    // missing/omitted. Sometime array is missing/response in array is
  .    // getting changed, getting lot of unwanted stuff Or whatever you can
  .    // think. And because of this I need to parse it manually.
  .
}

Now how can I parse this type of response manually in data class of Kotlin? One more thing I would like to know, can I use any base class for common fields in the response?

应该是这样的:

data class Response(val status: String, val apiId: Int , val message: String)

jackson-databind has @JsonIgnoreProperties(ignoreUnknown=true) annotation which can ignore unwanted json fields. then what you need to do is write a data class like below

@JsonIgnoreProperties(ignoreUnknown=true)
data class Response(val status: String, val apiId: Int, val message: String)

I found this code in googlemaps repository that provides manually parsing JSON object without 3rd party libraries. It parses JSON coordinates and seems pretty workable. The example of input JSON and code below:

[{"lat" : 51.5145160, "lng" : -0.1270060 },
{ "lat" : 51.5064490, "lng" : -0.1244260, "title" : "Corinthia Hotel London", "snippet": "Whitehall Pl"},
{ "lat" : 51.5097080, "lng" : -0.1200450,  "title" : "Savoy Place", "snippet" : "Covent Garden"},
{ "lat" : 51.5090680, "lng" : -0.1421420, "title" : "Albemarle St", "snippet": "Mayfair"},
{ "lat" : 51.4976080, "lng" : -0.1456320, "title" : " Victoria Square", "snippet": " Belgravia" },
{ "lat" : 51.5046150, "lng" : -0.1473780}]

 /**
 * Returns a list of cluster items read from the provided [inputStream]
 */
@Throws(JSONException::class)
fun read(inputStream: InputStream): List<MyItem> {
    // This matches only once in whole input so Scanner.next returns whole InputStream as a
    // String. http://stackoverflow.com/a/5445161/2183804
    val REGEX_INPUT_BOUNDARY_BEGINNING = "\\A"

    val items = mutableListOf<MyItem>()
    val json = Scanner(inputStream)
        .useDelimiter(REGEX_INPUT_BOUNDARY_BEGINNING).next()
    val array = JSONArray(json)
    for (i in 0 until array.length()) {
        var title: String? = null
        var snippet: String? = null
        val `object` = array.getJSONObject(i)
        val lat = `object`.getDouble("lat")
        val lng = `object`.getDouble("lng")
        if (!`object`.isNull("title")) {
            title = `object`.getString("title")
        }
        if (!`object`.isNull("snippet")) {
            snippet = `object`.getString("snippet")
        }
        items.add(MyItem(LatLng(lat, lng), title, snippet))
    }
    return items
}

And the final item is:

data class MyItem(val latLng: LatLng, val myTitle: String?, val mySnippet: String?) : ClusterItem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM