简体   繁体   中英

Scala JSON Parsing Nested Array into Case Class

I'm using the standard Scala json parsing and I am running into issues with the nested arrays.

Here is sample JSON:

{
    "_id": "id_here",
    "_rev": "rev_here",
    "RandomHosts": [
        "randomhosts_1",
        "randomhosts_2",
        "randomhosts_3",
        "randomhosts_4"
    ],
    "FirstObject": {
        "Host": "ActualHost",
        "Port": 8888,
        "DB": 0,
        "WFMDB": 1,
        "ETLDB": 2,
        "HostListPrefix": "Dev1",
        "ExtraHostsBands": [
            {
                "Host": "dev2",
                "Port": 2222,
                "DB": 0,
                "WFMDB": 1,
                "ETLDB": 2,
                "HostListPrefix": "Dev2"
            },
            {
                "Host": "dev3",
                "Port": 3333,
                "DB": 0,
                "WFMDB": 1,
                "ETLDB": 3,
                "HostListPrefix": "Dev3"
            }
        ],
        "RandomObject":{}
    }
}
// I HAVE OTHER IMPORTS AS WELL
import scala.util.parsing.json._;

case class BandClass (
        Host: String,
        Port:Int,
        DB:Int,
        WFMDB:Int,
        ETLDB:Int,
        HostListPrefix:String
    );

var jsonString = "<myjson>";

val bandconfig = JSON.parseFull(jsonString);
// THIS WORKS PERFECT AND GIVES ME JOINED STRING
val random_hosts = bandconfig.get.asInstanceOf[Map[String, Any]]("RandomHosts").asInstanceOf[List[String]].mkString(",");

//THIS ALSO WORKS PERFECT AND GIVES ME HOST AND PORT
val firstObject = bandconfig.get.asInstanceOf[Map[String, Any]]("FirstObject").asInstanceOf[Map[String, Any]];
val firstObjectHost = firstObject("Host").asInstanceOf[String]
val firstObjectPort = firstObject("Port").asInstanceOf[Double].toInt

//THIS IS WHERE EVERYTHING FALLS APART
val extraBands = firstObject("ExtraHostBands").asInstanceOf[List[BandClass]]

//EVEN THIS DOESNT WORK
val extraBands2 = firstObject("ExtraHostBands").asInstanceOf[Map[String, Any]]

Caused by: java.lang.ClassCastException: scala.collection.immutable.HashMap$HashTrieMap cannot be cast to $BandClass

I'm not sure how to force that nested json array into my case class. Id even settle for a map or seq or anything I could iterate over to get the host/ports out of the ExtraHostBand json objects.

Can anyone point me in the correct direction to get that json array into case class? I also have access to play-json but cant seem to figure that out either.

Ended up going to play-json and it worked really well. Here is a solution in case someone needs this in the future:

import play.api.libs.json.Json;
import play.api.libs.json;
import play.api.libs.json.Writes;
import play.api.libs.json._;
import play.api.libs._;
import play.api.libs.functional.syntax._;
import play.api.libs.json.Reads._;


case class BandClass (
        Host: String,
        Port:Int,
        DB:Int,
        WFMDB:Int,
        ETLDB:Int,
        HostListPrefix:String
    )

    case class FirstObject (
        Host: String,
        Port:Int,
        DB:Int,
        WFMDB:Int,
        ETLDB:Int,
        HostListPrefix:String,
        ExtraHostsBands: List[BandClass]
    )

    case class RawConfig (
        _id: String,
        _rev: String,
        RandomHosts: List[String],
        FirstObject: FirstObject
    )

    implicit val bandClassFormat = Json.format[BandClass];
    implicit val firstObjectFormat = Json.format[FirstObject];
    implicit val rawConfigFormat = Json.format[RawConfig];


    val playJsonParse = Json.parse(<myjson>).as[RawConfig]; 
    println("playJSON ID " + playJsonParse._id)
    println("playJSON REV " + playJsonParse._rev)

    playJsonParse.FirstObject.ExtraHostBands.foreach
        {
            case(r) => {
                println("Host " + r.Host);
                println("Host Prefix " + r.HostListPrefix);
                println("ETLDB " + r.ETLDB);
            }
        }

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