I have played a little with Spray Json - A lightweight, clean and simple JSON implementation in Scala
Here is an example of how to easily marshalling a google get reponse for some adderss, using Spray Json and case classes that were built for the responding json.
I hope that anyone who are trying to do so, would save a little time by using the ready to use case classes (Maybe it's a good idea to create a central repository of case classes for common used jsons).
That's the 1st result for searching "melbourne australia" in google maps (originally an array of 2 results).:
{
"results" : [
{
"address_components" : [
{
"long_name" : "Melbourne",
"short_name" : "Melbourne",
"types" : [ "colloquial_area", "locality", "political" ]
},
{
"long_name" : "Victoria",
"short_name" : "VIC",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "Australia",
"short_name" : "AU",
"types" : [ "country", "political" ]
}
],
"formatted_address" : "Melbourne VIC, Australia",
"geometry" : {
"bounds" : {
"northeast" : {
"lat" : -37.4598457,
"lng" : 145.76474
},
"southwest" : {
"lat" : -38.2607199,
"lng" : 144.3944921
}
},
"location" : {
"lat" : -37.814107,
"lng" : 144.96328
},
"location_type" : "APPROXIMATE",
"viewport" : {
"northeast" : {
"lat" : -37.4598457,
"lng" : 145.76474
},
"southwest" : {
"lat" : -38.2607199,
"lng" : 144.3944921
}
}
},
"partial_match" : true,
"place_id" : "ChIJ90260rVG1moRkM2MIXVWBAQ",
"types" : [ "colloquial_area", "locality", "political" ]
}
],
"status" : "OK"
}
And that's the Code, including the case classes that are used for parsing the json:
/**
* Created by gilad on 24/02/16.
*/
import spray.json._
import DefaultJsonProtocol._
import scala.io.Source.fromURL
object FetchCoordinates extends App{
@throws(classOf[java.io.IOException])
@throws(classOf[java.net.SocketTimeoutException])
def get(url: String,
connectTimeout:Int =5000,
readTimeout:Int =5000,
requestMethod: String = "GET") = {
import java.net.{URL, HttpURLConnection}
val connection = (new URL(url)).openConnection.asInstanceOf[HttpURLConnection]
connection.setConnectTimeout(connectTimeout)
connection.setReadTimeout(readTimeout)
connection.setRequestMethod(requestMethod)
val inputStream = connection.getInputStream
val content = io.Source.fromInputStream(inputStream).mkString
if (inputStream != null) inputStream.close
content
}
try {
val address = "melbourneaustralia"
val content = get("http://maps.googleapis.com/maps/api/geocode/json?address="+address+"&sensor=true")
val contentJs=content.parseJson
val googleRes = contentJs.convertTo[GoogleMapResponse]
val form_address= googleRes.results(0).formatted_address
println(googleRes.status)
} catch {
case ioe: java.io.IOException => // handle this
case ste: java.net.SocketTimeoutException => // handle this
}
}
Case classes:
import spray.json._
import DefaultJsonProtocol._
case class JsonCoords(lat:Long,lng:Long)
object JsonCoords { implicit val f = jsonFormat2(JsonCoords.apply)}
case class JsonBounds(northeast:JsonCoords,southwest:JsonCoords)
object JsonBounds { implicit val f = jsonFormat2(JsonBounds.apply)}
case class JsonGeometry(bounds:JsonBounds,location_type:String, viewport: JsonBounds)
object JsonGeometry { implicit val f = jsonFormat3(JsonGeometry.apply)}
case class JsonAddress(long_name:String,short_name:String,types:Seq[String])
object JsonAddress { implicit val f = jsonFormat3(JsonAddress.apply)}
case class JsonGoogleResult(address_components:Seq[JsonAddress],formatted_address:String,
geometry:JsonGeometry,partial_match:Boolean,place_id:String,types:Seq[String]
)
object JsonGoogleResult { implicit val f = jsonFormat6(JsonGoogleResult.apply)}
case class GoogleMapResponse(results:Seq[JsonGoogleResult],status:String)
object GoogleMapResponse { implicit val f = jsonFormat2(GoogleMapResponse.apply)}