Kotlin: JSON string with linebreaker and variable - json

I would like to add linebreakers to a JSON string so it will be more readable.
val myString = "some string"
val myObjectJson = `
{
"example1": "value",
"example2": $myString
}`
So later I can use ObjectMapper to create an object. objectMapper.readValue(myObjectJson, MyClass::class.Java)
What I'm trying to figure out:
How to add lineBreaker in Json string?
Tried template literals:"`", doesn't seem to work in Kotline. gives Expecting an expression error.
How to use variable in Json string?
This might go away after I figure out how to add linebreakers.

(Edited because I think I have misunderstood your question).
Are you asking how to lay out a JSON string in the source code? If so then what you are looking for is the Raw String feature implemented with 3 double-quotes like this:
val myObjectJson = """
{
"example1": "value",
"example2": $myString
}
"""
But in case you asking
How to add lineBreaker in Json string?
(Assuming you are using Jackson's ObjectMapper)
Simply use writerWithDefaultPrettyPrinter() like this: MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(value)
If that is not good enough for you I suppose you could implement a custom Pretty Printer: https://www.javadoc.io/static/com.fasterxml.jackson.core/jackson-core/2.14.2/com/fasterxml/jackson/core/PrettyPrinter.html

Related

Enumerating of JObject of NewtonSoft.Json loses '\' character in C#

I would like to parse json string using JObject.Parse() of NewtonSoft.Json. Assume that the json string is like this:
{"json":"{\"count\":\"123\"}"}
The result of jObject.First.ToString() is "json": "{\"count\":\"123\"}".
The result of jObject["json"].ToString() is {"count":"123"}. Enumerating gets the same result as this.
The testing code I used is like this.
[TestMethod()]
public void JsonParseTest()
{
var json = "{\"json\":\"{\\\"count\\\":\\\"123\\\"}\"}";
var jObject = JObject.Parse(json);
Console.WriteLine($"json : {json}");
Console.WriteLine($"jObject.First.ToString() : {jObject.First}");
Console.WriteLine($"jObject[\"json\"].ToString() : {jObject["json"]}");
}
We can see that enumerating of jObject will lose the character '\'. What is the problem? I would be appreciated for any suggestion :)
EDIT 1
The version of NewtonSoft is 12.0.3 released in 2019.11.09.
The parser isn't loosing anything. There is no literal \ in your example. The backslashes are purely part of the JSON syntax to escape the " inside the string vlue. The value of the key json is {"count":"123"}.
If you want to have backslashes in that value (however I don't see why you would want that), then you need add them, just like you added them in your C# string (C# and JSON happen to have the same escaping mechanism):
{"json":"{\\\"count\\\":\\\"123\\\"}"}
with leads to the C# code:
var json = "{\"json\":\"{\\\\\\\"count\\\\\\\":\\\\\\\"123\\\\\\\"}\"}";

PlayJSON in Scala

I am trying to familiarize myself with the PlayJSON library. I have a JSON formatted file like this:
{
"Person": [
{
"name": "Jonathon",
"age": 24,
"job": "Accountant"
}
]
}
However, I'm having difficulty with parsing it properly due to the file having different types (name is a String but age is an Int). I could technically make it so the age is a String and call .toInt on it later but for my purposes, it is by default an integer.
I know how to parse some of it:
import play.api.libs.json.{JsValue, Json}
val parsed: JsValue = Json.parse(jsonFile) //assuming jsonFile is that entire JSON String as shown above
val person: List[Map[String, String]] = (parsed \ "Person").as[List[Map[String, String]]]
Creating that person value throws an error. I know Scala is a strongly-typed language but I'm sure there is something I am missing here. I feel like this is an obvious fix too but I'm not quite sure.
The error produced is:
JsResultException(errors:List(((0)/age,List(JsonValidationError(List(error.expected.jsstring),WrappedArray())))
The error you are having, as explained in the error you are getting, is in casting to the map of string to string. The data you provided does not align with it, because the age is a string. If you want to keep in with this approach, you need to parse it into a type that will handle both strings and ints. For example:
(parsed \ "Person").validate[List[Map[String, Any]]]
Having said that, as #Luis wrote in a comment, you can just use case class to parse it. Lets declare 2 case classes:
case class JsonParsingExample(Person: Seq[Person])
case class Person(name: String, age: Int, job: String)
Now we will create a formatter for each of them on their corresponding companion object:
object Person {
implicit val format: OFormat[Person] = Json.format[Person]
}
object JsonParsingExample {
implicit val format: OFormat[JsonParsingExample] = Json.format[JsonParsingExample]
}
Now we can just do:
Json.parse(jsonFile).validate[JsonParsingExample]
Code run at Scastie.

How to convert response body in Json using play framework

override def accessToken(): ServiceCall[RequestTokenLogIn, Done] = {
request=>
val a=request.oauth_token.get
val b=request.oauth_verifier.get
val url=s"https://api.twitter.com/oauth/access_token?oauth_token=$a&oauth_verifier=$b"
ws.url(url).withMethod("POST").get().map{
res=>
println(res.body)
}
The output which I am getting on terminal is
oauth_token=xxxxxxxxx&oauth_token_secret=xxxxxxx&user_id=xxxxxxxxx&screen_name=xxxxx
I want to convert this response in json format.like
{
oauth_token:"",
token_secret:"",
}
When Calling res.json.toString its not converting into jsValue.
Is there any other way or am I missing something?
According to the documentation twitter publishes, it seems that the response is not a valid json. Therefore you cannot convert it automagically.
As I see it you have 2 options, which you are not going to like. In both options you have to do string manipulations.
The first option, which I like less, is actually building the json:
print(s"""{ \n\t"${res.body.replace("=", "\": \"").replace("&", "\"\n\t\"")}" \n}""")
The second option, is to extract the variables into a case class, and let play-json build the json string for you:
case class TwitterAuthToken(oauth_token: String, oauth_token_secret: String, user_id: Long, screen_name: String)
object TwitterAuthToken {
implicit val format: OFormat[TwitterAuthToken] = Json.format[TwitterAuthToken]
}
val splitResponse = res.body.split('&').map(_.split('=')).map(pair => (pair(0), pair(1))).toMap
val twitterAuthToken = TwitterAuthToken(
oauth_token = splitResponse("oauth_token"),
oauth_token_secret = splitResponse("oauth_token_secret"),
user_id = splitResponse("user_id").toLong,
screen_name = splitResponse("screen_name")
)
print(Json.toJsObject(twitterAuthToken))
I'll note that Json.toJsObject(twitterAuthToken) returns JsObject, which you can serialize, and deserialize.
I am not familiar with any option to modify the delimiters of the json being parsed by play-json. Given an existing json you can manipulate the paths from the json into the case class. But that is not what you are seeking for.
I am not sure if it is requires, but in the second option you can define user_id as long, which is harder in the first option.

Replacing a number variable in json using groovy

I have a json which has some numbers that I want to make dynamic and replace the value using groovy. Please let me know if there is a better way as I have already used toInteger to convert but not working.
For ex
{
jobName:"",
protocolName:"tcp",
portNo:""
}
I am able to replace the job-name which is string using replace in groovy but I am not able to replace the port number. The final json should look like below
{
jobName:"myjob",
protocolName:"tcp",
portNo:1112
}
Please let me know if there is a way to do that in groovy
Something like this:
String str = '{ "jobName":"", "protocolName":"tcp", "portNo":"" }'
def json = new JsonSlurper().parseText(str)
json.jobName = 'myJob'
json.portNo = 1112
println new JsonOutput().prettyPrint(new JsonOutput().toJson(json))

How to extract the numbers from json path using scala

My response will be like:
{
"code" : 201,
"message" : "Your Quote Id is 353541551"
}
From this above response I have to extract the number 353541551 alone, so I tried with the basic scala snippets. I tried the following:
.check((status is 201),(jsonPath("Your Quote Id is(//d{9})").saveAs("quoteid")))
And another snippet:
.check((status is 201),(jsonPath("$.message.([0-9]+)").saveAs("quoteid")))
But both didn't work
Please help me out to extract the numbers
Try to use spary json; https://github.com/spray/spray-json
You can define json data structure using scala case class and define custom apply/unapply methods if required.
case class JsonResponse(code: Int, message: String)
object JsonResponse { implicit val f = JsonFormat2(JsonResponse.apply)}
you can use scala Regex to pattern match the string to extract the required value.