我有以下json对象包含json对象列表。这些对象中的每一个都包含有关工作站对象的信息。
"stations": [
{
"cryptName": "Tv_Gara Nord 1",
"easyName": "Gara de Nord",
"lat": 45.750287,
"lng": 21.207498
},
{
"cryptName": "Tv_R Carol 1",
"easyName": "Regele Carol I",
"lat": 45.745068,
"lng": 21.211034
},
{
"cryptName": "Tv_Mocioni 1",
"easyName": "Piata Mocioni (Sinaia)",
"lat": 45.746343,
"lng": 21.21551
}]
我已经尝试了这个,我无法将其转换为格式为的ArrayBuffer:
ArrayBuffer(List(" cryptName"," easyName"," lat"," lng"),...)
[第73行.. 77] 问题在于(js \\\ "cryptName")(0) ... (js \\\ "lng")(0)
。
如何将所有这些非单一电台正确存储到我的ArrayBuffer中?
package backend
import scala.concurrent.duration._
import scala.collection.immutable.Seq
import scala.concurrent.forkjoin.ThreadLocalRandom
import akka.actor.{ ActorRef, Props }
import play.api.libs.json.Json
import play.extras.geojson.{ LineString, LatLng, FeatureCollection }
import play.api.Logger
import actors.GeoJsonBot
import java.net.URL
import akka.actor.Actor
import scala.io.Source
import akka.cluster.Cluster
import play.api.libs.json.JsValue
import org.apache.commons.lang3.Validate
object BotManager
{
def props(regionManagerClient: ActorRef, data: Seq[URL]): Props = Props(new BotManager(regionManagerClient, data))
private case object Tick
}
/**
* Loads and starts GeoJSON bots
*/
class BotManager(regionManagerClient: ActorRef, data: Seq[URL]) extends Actor
{
import BotManager._
var total = 0
val max = Settings(context.system).TotalNumberOfBots
import context.dispatcher
val tickTask = context.system.scheduler.schedule(1.seconds, 3.seconds, self, Tick)
val port = Cluster(context.system).selfAddress.port.get
override def postStop(): Unit = tickTask.cancel()
def receive =
{
case Tick if total >= max => tickTask.cancel()
case Tick =>
val totalBefore = total
val originalTrail = total == 0
println("NODE: " + data)
data.zipWithIndex.foreach
{
case (url, id) =>
val json = Json.parse(Source.fromURL(url).mkString)
println("URL: " + url + "ID: " + id)
Json.fromJson[FeatureCollection[LatLng]](json).fold(
{
invalid =>
Logger.error("Error loading geojson bot: " + invalid)
}, valid => valid.features.zipWithIndex.map
{
feature => feature._1.geometry match
{
case route: LineString[LatLng] if total < max => total += 1
val userId = "bot-" + total + "-" + port + "-" + id + "-" + feature._1.id.getOrElse(feature._2) + "-" + feature._1.properties.flatMap(js => (js \ "name").asOpt[String]).getOrElse("") + feature._1.properties.flatMap(js => (js \ "segment").asOpt[String]).getOrElse("")
val stations = feature._1.properties.flatMap(js => (js \ "stations").asOpt[JsValue])
import play.api.libs.json.JsObject
import play.api.libs.json.JsArray
var stationss = feature._1.properties.flatMap(js => (js \ "stations").asOpt[JsValue])
val crypt = stationss.flatMap(js => (js \\ "cryptName")(0).asOpt[JsValue])
val ename = stationss.flatMap(js => (js \\ "easyName")(0).asOpt[JsValue])
val lat = stationss.flatMap(js => (js \\ "lat")(0).asOpt[JsValue])
val lng = stationss.flatMap(js => (js \\ "lng")(0).asOpt[JsValue])
case class Station(cryptName: String, easyName: String, lat: Float, lng: Float)
implicit val readsStation = Json.reads[Station]
case class Stations(stations: List[Station])
implicit val readsStations = Json.reads[Stations]
val stations = Json.parse(text).as[Stations].stations.map(s => List(s.cryptName, s.easyName, s.lat, s.lng)).to[ArrayBuffer]
println("List: [" + crypt.get + ", " + ename.get + ", " + lat.get + ", " + lng.get + "]")
val offset =
if (originalTrail) (0.0, 0.0)
else (ThreadLocalRandom.current.nextDouble() * 15.0,
ThreadLocalRandom.current.nextDouble() * -30.0)
context.actorOf(GeoJsonBot.props(route, stations, offset, userId, regionManagerClient))
case other =>
}
})
}
println("Started " + (total - totalBefore) + " bots, total " + total)
}
}
答案 0 :(得分:2)
我会这样做:
case class Station(cryptName: String, easyName: String, lat: Float, lng: Float)
implicit val readsStation = Json.reads[Station]
case class Stations(stations: List[Station])
implicit val readsStations = Json.reads[Stations]
(假设JSON为{ stations: [ ... ] }
)
然后使用以下内容:
val stations = Json.parse(text).as[Stations].stations
.map(s => List(s.cryptName, s.easyName, s.lat, s.lng)).to[ArrayBuffer])
将生成以下内容(给出您的样本):
ArrayBuffer(List(Tv_Gara Nord 1, Gara de Nord, 45.750286, 21.207499), List(Tv_R Carol 1, Regele Carol I, 45.745068, 21.211035), List(Tv_Mocioni 1, Piata Mocioni (Sinaia), 45.74634, 21.21551))
答案 1 :(得分:1)
使用Reads\Writes
宏。
创建案例类,例如
case class Station(cryptName: String, easyName: String, lat: String, long: String)
case class Stations(stations: Seq[Station])
创建阅读,
import play.api.libs.json._
import play.api.libs.functional.syntax._
implicit val stationReads = Json.reads[Station]
implicit val stationsReads = Json.reads[Stations]
做转换,
val json: JsValue = Json.parse(jsonString)
Json.fromJson[Stations](json) match {
case JsSuccess(t, _) => ???
case any: JsError => ???
}