Convert scala Map to Json in play framework - json

I am trying to convert a Map to Json in play framwork 2.6.x.
The code is like
def toJson(x:Map[String, Object]) = {
import play.api.libs.json._
Json.toJson(x)
}
I got error No Json serializer found for type Map[String,Object]. Try to implement an implicit Writes or Format for this type.
The I add writes and code becomes:
def toJson(x:Map[String, Object]) = {
import play.api.libs.json._
implicit val writes = Json.writes[Map[String, Object]]
Json.toJson(x)
}
I hit error. No apply function found for scala.collection.immutable.Map

Related

Reading JSON RDD using Spark Scala

I am receiving JSON data from Kafka brokers and I am reading it using Spark Streaming and Scala. Following is the example data:
{"timestamp":"2020-12-11 22:35:00.000000 UTC","tech":"Spark","version":2,"start_time":1607725688402210,"end_time":1607726131636059}
I receive this data as RDD[String] in my Scala code , now I want to read particular key from each data row, for example 'version' from the above data.
I am able to do this as follows:
for(record <- rdd){
val jsonRecord = JSON.parseFull(record );
val globalMap = jsonRecord.get.asInstanceOf[Map[String, Any]]
val version = globalMap.get("version").get.asInstanceOf[String]
}
But I am not sure if this is the best way to read RDD having JSON data. Please suggest.
Thanks,
Use json4s library to parse json data & It will be available with spark default no need to import extra libraries.
Check below code.
scala> rdd.collect.foreach(println)
{"timestamp":"2020-12-11 22:35:00.000000 UTC","tech":"Spark","version":2,"start_time":1607725688402210,"end_time":1607726131636059}
scala> :paste
// Entering paste mode (ctrl-D to finish)
rdd.map{ row =>
// Import required libraries for json parsers.
import org.json4s._
import org.json4s.jackson.JsonMethods._
implicit val formats = DefaultFormats
// parse json message using parse function from json4s lib.
val jsonData = parse(row)
// extract required fields from parsed json data.
// extracting version field value
val version = (jsonData \\ "version").extract[Int]
// extracting timestamp field value
val timestamp = (jsonData \\ "timestamp").extract[String]
(version,timestamp)
}
.collect
.foreach(println)
// Exiting paste mode, now interpreting.
(2,2020-12-11 22:35:00.000000 UTC)

How do I catch a JSON parse error when using acceptWithActor with custom types?

I'm using websockets in Play framework 2.3.
Referencing this snippet from the official how-to page.
import play.api.mvc._
import play.api.Play.current
def socket = WebSocket.acceptWithActor[InEvent, OutEvent] { request => out =>
MyWebSocketActor.props(out)
}
How would I catch a JSON parse error (RuntimeException: Error parsing JSON)?
This question is very similar to the one linked below, however, I'm using custom types (InEvent, OutEvent) and not the JsValue type. I don't want to transform to a JsValue or string. I need it to transform to the InEvent type if successful, or throw a more descriptive error.
How do I catch json parse error when using acceptWithActor?
Somewhere within your scope there are implicit definitions of FrameFormatter[InEvent] and FrameFormatter[OutEvent]:
implicit val inEventFrameFormatter = FrameFormatter.jsonFrame[InEvent]
implicit val outEventFrameFormatter = FrameFormatter.jsonFrame[OutEvent]
You just have to rewrite both of them, instead of using the predefined jsonFrame a custom method like customJsonFrame:
def customJsonFrame[A: Format]: FrameFormatter[A] =
FrameFormatter.jsonFrame.transform[A](
out => Json.toJson(out),
in => Json.fromJson[A](in).fold(
error => throw new CustomException(),
a => a
)
)
and replace the aforementioned rows with:
implicit val inEventFrameFormatter = customJsonFrame[InEvent]
implicit val outEventFrameFormatter = customJsonFrame[OutEvent]

Issue with json conversions for scalax graph library for scala

We are using graph-json 1.11.0 and graph-core-1.11.5 with in a play 2.5.x application .
http://www.scala-graph.org/
The user guide examples for toJson and fromJson for a graph , do not wok with the current stable 1.11.0 release .
Ref : http://www.scala-graph.org/guides/json.html
We make use of a simple string graph in our application
Graph[String,DiEdge] .
We managed to write the graph to json conversion part , but unable to identify the exact fromJson syntax for the new stable version .
Below is a sample code used in our application . Can some one help us on how to convert json to graph.
import play.api.libs.json.{JsValue, Json}
import scalax.collection.Graph
import scalax.collection.GraphEdge.DiEdge
import scalax.collection.io.json.JsonGraph
import scalax.collection.io.json.descriptor.Descriptor
import scalax.collection.io.json.descriptor.predefined.Di
import scalax.collection.io.json.descriptor.{Descriptor, StringNodeDescriptor}
object HierarchyGraph {
val descriptor = new Descriptor(StringNodeDescriptor,Di.descriptor[String]())
def toJson(graph : Graph[String, DiEdge]) : JsValue = {
val jsText = JsonGraph(graph).toJson(descriptor)
try {
Json.parse(jsText)
} catch {
case e : Exception => Json.toJson(Json.obj())
}
}
def fromJson(graphAsJsValue : JsValue) : Graph[String,DiEdge] = {
// json to graph conversion code here
}
}
Issue addressed by peter-empen on github .
https://github.com/scala-graph/scala-graph/issues/71

Producing json in a Scala app using json4s

I am attempting to produce JSON in a Scala app using json4s. Fairly straight forward, Here's some sample value I put together to test it in my Scalatra app:
import org.json4s._
import org.json4s.JsonDSL._
object JsonStub {
val getPeople =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))
}
In my controller, I simply have:
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.{DefaultFormats, Formats}
class FooController(mongoDb: MongoClient)(implicit val swagger: Swagger) extends ApiStack with NativeJsonSupport with SwaggerSupport {
get ("/people", operation(getPeople)) {
JsonStub.getPeople
}
}
The output I'm seeing in the browser however, is the following:
{
"_1": "people",
"_2": {
"person_id": 5,
"test_count": 5
}
}
Any clue where the _1 and _2 keys are coming from? I was expecting this output instead:
{
"people":{
"person_id": 5,
"test_count": 5
}
}
What you're seeing in the output is a reflectively serialized tuple, which has fields _1 and _2. This is because the return type that the compiler has inferred for JsonStub.getPeople is Tuple2[String, JObject].
The json4s DSL uses implicit conversions to turn values like the tuple into a JValue. But, if you don't tell the compiler you wanted a JValue, it won't apply the conversion.
Ideally, this would result in a compile error, because you tried to produce JSON from something that isn't the right type. Unfortunately, because your web framework assumes you want to fall back to reflection-based serialization, it means there is another way to turn the tuple into JSON, which isn't what you wanted.
If you explicitly tell the compiler that you want a JValue and not a Tuple2, the DSL's implicit conversion will be applied in the correct place.
val getPeople: JValue =
("people" ->
("person_id" -> 5) ~
("test_count" -> 5))

Output parsed JSON to template in lift

Using Lift's json parser, how can I output parsed json objects into a template?
The datatypes that net.liftweb.json.JsonParser provides are not
standard lists.
package rem.lift_client
package snippet
import net.liftweb._
import util._
import Helpers._
import net.liftweb.json.JsonParser._
class SearchResults {
def render() = {
val json_raw = "[ {\"userName\":\"John\"}, {\"userName\":\"Michael\"} ]"
val json_parsed = parse(input)
"li *" #> json_parsed.toString <---- NOT CORRECT
}
}
In the above example, I wanted to output a list of users as:
John
Michael
How do I interpret the parsed object? Any ideas are welcome, thanks.
NOTE: In addition to the accepted answer, lift-json has an excellent documentation on this subject.
One way is to extract the data with case classes.
implicit val formats = DefaultFormats
case class User(userName: String)
json_parsed.extract[List[User]]