kotlin klaxon library for json - java

i'm new to kotlin and decided that best way to learn something is to start using it(So question related more to language than to klaxon library). I'm trying to understand very first snippet from git page of klaxon(https://github.com/cbeust/klaxon).
Here it is:
fun parse(name: String) : Any? {
val cls = Parser::class.java
return cls.getResourceAsStream(name)?.let { inputStream ->
return Parser().parse(inputStream)
}
}
I don't understand why in first case we do
Parser::class.java
and then calling getResource...
But then just call
Parser().parse
in second case. What's the difference and why it's like that
P.S Sorry for bad english=)

Okay, i just figured it out, we need ::class.java because getResourceAsStream is java.lang.Class function. And parse is a member function of Parser class.

Hi Yarick I made easy version of parse function. What I am doing here. I am parsing json api request response as string in function then creating parsing and returning it as JsonObject
Note: Use stringbuilder to create mutable string.
// Json Parsing Object
fun parse(name: String): JsonObject {
val parser = Parser()
val stringBuilder: StringBuilder = StringBuilder(name)
val json: JsonObject = parser.parse(stringBuilder) as JsonObject
return json
}

Related

How get just one value from json as string

I have following json as string:
{
"field1":"value1",
"field2":"value2",
"field3":{
"field31":"value31",
"field32":"value32"
},
"field4":{
"field41":"value41"
}
}
What is the best and the most modern way to get from this json just value from field41, so I would return "value41". I know that I can use JSONObject but I'm wondering weather we have any other better option?
Try JSONPath
String json = "...";
String field41 = JsonPath.read(json, "$.field4.field41");
You can test it here - https://jsonpath.herokuapp.com/
If you want to generate a real object out of it you can use Gson. You need to describe the class first. There are online json to Java objects converters out there. And then you can just call:
YourObject obj = new Gson().fromJson(json,YourObject.class);
System.out.println(obj.getField4().getField41());
And there you have it!

return a Mono<String> from FilePart (Java)

a class UploadService receives a FilePart, representing the content of the JSON below, from a REST API.
The target is to return a Mono<String> from this FilePart to build a JSONObject.
This is the posted JSON:
{
"machineId" : "7",
"printJobId" : "123",
"timeStampStartPrintJob" : "10:23:15,253",
"timeStampEndPrintJob" : "12:50:16,577",
"optionalMetadata" : {}
}
This is my code:
public class UploadService{
public Mono<String> uploadSensorData(FilePart metaDataFile) {
/*create + print a JSONObject*/
JSONObject result = new JSONObject(metaDataFileContentToString(metaDataFile).toString().trim().charAt(0));
System.out.println(result);
}
/*convert FilePart to String*/
private Mono<String> metaDataFileContentToString(FilePart metaDataFile) {
return metaDataFile.content()
.map(buffer -> buffer.toString(StandardCharsets.UTF_8))
.collectList()
.map(list -> String.join("", list));
}
return null;
}
Issue: I'm not sure if I'm on the right track with my method metaDataFileContentToString. By now the output only shows the first and last curly bracket of the JSON: {}
Is there another way to get a proper Mono<String> from the bytes of the Filepart? Or is maybe the .toString() method by creating the JSONObject the problem?
Many thanks for your ideas in advance!
The target is to return a Mono<String> from this FilePart to build a JSONObject
There's no need to do this - modern JSON libraries like Jackson have built in methods to asynchronously process a Flux<DataBuffer> straight into the type that's required, skipping the String.
So assuming you have a class PrintJobInfo that represents your data structure, you can just do something like:
Mono<PrintJobInfo> mono = new Jackson2JsonDecoder()
.decodeToMono(fp.content(), ResolvableType.forClass(PrintJobInfo.class), null, null)
.cast(PrintJobInfo.class);
In real-world use you'd probably want to expose your Jackson2JsonDecoder as a bean rather than creating a new one each time. Note it also has another constructor that can take an ObjectMapper if you need any custom configuration.
What string do you want?
If you want a print of the json then use ObjectMapper::writeValueAsString or similar, or yes, toString.
To get a Mono then use Mono::just
However, you should not creat a Mono in your methods but rather you should be part of an existing flow. This means you should be getting a Mono and returning a Mono and your function is simply mapping the data from one type to another.
public Mono<String> uploadSensorData(Mono<FilePart> metaDataFile) {
return metaDataFile.map(FilePart::toString);
}

How to rename the key of a JSON Response dynamically in Retrofit2 Android

I have a JSON response like this:
{
"AED_BDT": 23.100486
}
But the key changes according to my query like if my query is USD_BDT, then it will give response like this:
{
"USD_BDT": 23.100486
}
So,that means I need to change the JSON key according to my query. But I couldn't find any solution on how to do this.
I tried by converting the response body into String and then replaced the Key according to my query, but this is not working..
This is my model class:
data class ResponseCurrencyConvert(
val USD_BDT: Double
)
This is what I tried so far:
val params = HashMap<String,String>()
params["compact"]="ultra"
params["apiKey"]= API_KEY
params["q"]="${currencyFrom}_${currencyTo}"//getting specific currencies and then setting them as query,i.e:USD_BDT
message(TAG,"Query: ${params["q"]}")
prefManager.query=params["q"]!!
//calling the API
apiServices.convertCurrency(params).enqueue(object : Callback<ResponseCurrencyConvert>{
override fun onFailure(call: Call<ResponseCurrencyConvert>, t: Throwable) {
message(TAG,"onFailure: ${t.localizedMessage}")
}
override fun onResponse(call: Call<ResponseCurrencyConvert>, response: Response<ResponseCurrencyConvert>) {
message(TAG,"onResponse Code: ${response.code()}")
message(TAG,"onResponse Body: ${Gson().toJson(response.body())}")
val json = Gson().toJson(response.body())//converting the response as string
val oldValue = "USD_BDT"//the key which was in my model class
val newValue=params["q"]// the new key which is my query
val output = json.replace(oldValue,newValue!!,false) // replacing the default query with my query
val newResponse = Gson().fromJson(output,ResponseCurrencyConvert::class.java)//again converting the new replaced string to json
if (response.isSuccessful){
message(TAG,"Output: $output")
message(TAG,"onResponse Result: ${newResponse?.USD_BDT}")
message(TAG,"onResponse newResult: ${newResponse.USD_BDT}")
rate= newResponse?.USD_BDT//getting the value; this is returning 0 every time expect when my query is USD_BDT
I commented everything that I did on the code, please read that carefully. Your help is highly appreciated..
Keys are defined from the server only I guess
The best way you can do is like keep both keys and make it nullable
else you have an alternate name in JSON parsing
A way to do that is maintaining the 2 different keys, which is the most simple and effective.
Another way to accomplish this is changing the Response type to string. When you get the response you change the JSON string, changing the key name and then use GSON to manually convert from JSON to Object.
Maybe it can be done also with a Custom Json Converter, but I don't think is worth.
If the key changes for every other response, I would suggest using HashMap<String, String>. Instead of mapping directly to String value which changes dynamically using HashMap would solve your issue.
Let me know how it goes.

JSON Object to generic ParseFile Object, issue

I have run in to an issue, while converting my iOS app to android.
The database is structured such that there are "stations", these stations can have multiple images attached, in the parse database, the images are an array of imagePointers.
When i wanted to get the images out in iOS here is what i did:
stations = object in this case
// Get a single image
if ([[object objectForKey:#"imagePointers"] objectAtIndex:0] != [NSNull null]) {
PFFile *imageFile = [[[object objectForKey:#"imagePointers"] objectAtIndex:0] objectForKey:#"image"];
cell.coverImageView.file = imageFile;
[cell.coverImageView loadInBackground];
}
Its pretty simple, i just lift the imagePointers array and get objectAtIndex0, then i cast it to a parse file.
But i can't do this in android, here is what i have atm:
JSONArray imagePointers = thisStation.getJSONArray("imagePointers");
try {
JSONObject indexImage = imagePointers.getJSONObject(0);
} catch ( Exception e ) {
JSONObject indexImage = null;
}
Here i get the object at index 0 as a JSONObject, i cannot use this in a ParseFile Object, since i need to cast it as a generic type ParseFile.
How do i do this? Or is my approach completely incorrect?
Fixed it by avoiding casting to JSON, apparently there is a getList method
// Get parse Image as index image
ParseObject thisStation = stationItems.get(position);
List<ParseObject>imagePointers = thisStation.getList("imagePointers");
ParseFile image = imagePointers.get(0).getParseFile("image");
thumbnail.setParseFile(image);
thumbnail.loadInBackground();
I had the same issue for almost 2 days but finally I solved it by the getList method!
Now all you gotta do is use getList instead of getJSONObject or getJSONArray or whatever, because when you use them you will not be able to use the getParseFile for any of those believe me.
But instead you can do something like:
val obj = parseObject.getList("listname")
val file = obj[0].getParseFile("image")
Now, I don't remember how the syntex is or so but the key here is to use the getList method if you want to get list of all images you saved in a Back4app Parse JSONArray.
Hope you found it helpful.
Goodluck

How to obtain the content from Multi-Level JSON format in JAVA?

For example, a kind of JSON as below:
{ "x":"1","y":"2","z":{"a":"1","b":"2","c":"3"}}
Put this as string in JSONObject argument:
JSONObject jaob=new JSONObject(xxx)
and from method "get("x")" of JSONObject I can obtain the value "1"
jaob.get("x")
But how to get "a" of the second level JSON format "z"???
When I try to obtain by
JSONObject(jaob.get("z").toString()).get("a")
but it doesn't work.
Does any one have the idea?
Any response is appreciated, thanks
jaob.getJSONObject("Z").getString("a")
alternatively, you could use getLong or getString on a.
If you read the javadocs it's pretty easy stuff. The reason yours didn't work is that get returns a java.lang.Object not a JSONObject or JSONArray.
Have you tried
JSONObject jaob = new JSONObject(xxx);
jaob.getJSONArray("z");
//or
jaob.getJSONObject("z");
they both return JSONObject according to JSONObject

Categories