Double quotes issue in retrieving value from json object - json

I am using Spray json and converting http response to json object in following way and fetching value of WebId key from it:
val json = http_response.body.parseJson
val web_id = json.asJsObject().getFields("WebId")
println(web_id(0))
The output of http_response.body is : {"WebId":"F1AbETkR"}
the output of println is : "F1AbETkR"
The issue is web_id is coming in form of string with double quotes included which when concatenated in another http uri results in improper url formation.
It can be solved by simply stripping double quotes from beginning and end but Is there a better/easier/cleaner way of direct fetching of value without double quotes?

The problem is that you are trying to "print" the JsValue which is giving you these extra double-quotes, you need to convert the JsValue to String.
import spray.json._
// following import will provide implicit readers for `String` type
import DefaultJsonProtocol._
val jsonString = """{"WebId":"F1AbETkR"}"""
val webId = jsonString.parseJson.asJsObject.getFields("WebId")(0).convertTo[String]
// webId: String = F1AbETkR

Related

JsonSlurper parsing String containing Json into unexpected format

From a separate system I get a String parameter "messageJson" whose content is in the form:
{"agent1":"smith","agent2":"brown","agent3":{"agent3_1":"jones","agent3_2":"johnson"}}
To use it in my program I parse it with JsonSlurper.
def myJson = new JsonSlurper().parseText(messageJson)
But the resulting Json has the form:
[agent1:smith, agent2:brown, agent3:[agent3_1:jones, agent3_2:johnson]]
Note the square brackets and the lack of double quotes. How can I parse messageJson so that the original structure is kept?
Ok, thanks to the hint by cfrick, I was able to find a solution. In case anyone else has a similar problem, all I needed to do was using JsonOutput in the end to convert the map back to a Json
I.E. :
def myJson = new JsonSlurper().parseText(messageJson)
myJson << [agent4:"jane"]
def backToJson = JsonOutput.toJson(myJson)

Extract a Json from an array inside a json in spark

I have a complicated JSON column whose structure is :
story{
cards: [{story-elements: [{...}{...}{...}}]}
The length of the story-elements is variable. I need to extract a particular JSON block from the story-elements array. For this, I first need to extract the story-elements.
Here is the code which I have tried, but it is giving error:
import org.json4s.{DefaultFormats, MappingException}
import org.json4s.jackson.JsonMethods._
import org.apache.spark.sql.functions._
def getJsonContent(jsonstring: String): (String) = {
implicit val formats = DefaultFormats
val parsedJson = parse(jsonstring)
val value1 = (parsedJson\"cards"\"story-elements").extract[String]
value1
}
val getJsonContentUDF = udf((jsonstring: String) =>
getJsonContent(jsonstring))
input.withColumn("cards",getJsonContentUDF(input("storyDataFrame")))
According to json you provided, story-elements is a an array of json objects, but you trying to extract array as a string ((parsedJson\"cards"\"story-elements").extract[String]).
You can create case class representing on story (like case class Story(description: String, pageUrl: String, ...)) and then instead of extract[String], try extract[List[Story]] or extract[Array[Story]]
If you need just one piece of data from story (e.g. descrition), then you can use xpath-like syntax to get that and then extract List[String]

How to get list of json strings from sinlgle line multi json string in scala

I am trying to get list of json string from given string having multiple json strings separated by ",".
For example
val jsonString = "{\"a\":\"b\"},{\"c\":\"d\", \"e\":\"f\"}"
expected result , List[String] :
["{\"a\":\"b\"}", "{\"c\":\"d\", \"e\":\"f\"}"]
You should replace the json separator with a string or character that is not repeated in the whole string and use that special separator to be used with split method to get you your required output. Here I have used -
jsonString.replace("},{", "}-{").split("-")
You should have output as
res0: Array[String] = Array({"a":"b"}, {"c":"d", "e":"f"})
One step further, calling toList method would get you to the final dataType you require
jsonString.replace("},{", "}-{").split("-").toList //res0: List[String] = List({"a":"b"}, {"c":"d", "e":"f"})
Got solution for it.
val jsonString = "{\"a\":\"b\"},{\"c\":\"d\", \"e\":\"f\"}"
val jsonListString = "[" + jsonString + "]"
val jsonArray = new JSONArray(jsonListString)
This will create array of json.

Cut off the field from JSON string

I have a JSON string like this:
{"id":"111","name":"abc","ids":["740"],"data":"abc"}
I want to cut off the field "ids", however I don't know apriori the values like ["740"]. So, it might be e.g. ["888,222"] or whatever. The goal is to get the json string without the field "ids".
How to do it? Should I use JackMapper?
EDIT:
I tried to use JackMapper as JacksMapper.readValue[Map[String, String]](jsonString)to get only fields that I need. But the problem is that"ids":["740"]` throws the parsing error because it's an array. So, I decided to cut off this field before parsing, though it's an ugly solution and ideally I just want to parse the json string into Map.
Not sure what JackMapper is, but if other libraries are allowed, my personal favourites would be:
Play-JSON:
val jsonString = """{"id":"111","name":"abc","ids":["740"],"data":"abc"}"""
val json = Json.parse(jsonString).as[JsObject]
val newJson = json - "ids"
Circe:
import io.circe.parser._
val jsonString = """{"id":"111","name":"abc","ids":["740"],"data":"abc"}"""
val json = parse(jsonString).right.get.asObject.get // not handling errors
val newJson = json.remove("ids")
Note that this is the minimal example to get you going which doesn't handle bad input etc.

Create MongodbObject using bson.util

I have a JsValue(spray.json.JsValue) which is in JSON format. I need to convert this JSON value to a MongodbObject using bson.util. How can I do this ?
You've probably got an answer for this already, but since i was just looking for a way to do the same conversion I thought I'd leave an answer. This worked for me.
You can convert it to a String using spray.json and use the JSON.parse provided by com.mongodb.util.JSON.
The trick is to remove the additional double quotes at the start and end of the string so that JSON.parse recognises it as a json object instead of a JSON String.
import spray.json._
import DefaultJsonProtocol._
val json = "{'foo':'baa'}"
val jsValue = json.toJson
val slicedJson = jsValue.toString().slice(1, jsValue.toString().length - 1)
val dbObject = JSON.parse(slicedJson).asInstanceOf[DBObject]