JsonObject to Json records - format output - java

I am using the CryptoCompare API to pull the crypto symbol details; the output is
like below with nested JSON - I need to convert into Rerecords with below format:
{
"ETH":{
"USD":{
"FROMSYMBOL":"Ξ",
"TOSYMBOL":"$",
"MARKET":"CryptoCompare Index",
"PRICE":"$ 117.74",
"LASTUPDATE":"Just now",
"LASTVOLUME":"Ξ 0.01000",
"LASTVOLUMETO":"$ 1.17",
"LASTTRADEID":"44473885",
"VOLUMEDAY":"Ξ 340,510.0",
"VOLUMEDAYTO":"$ 39,874,960.0",
"VOLUME24HOUR":"Ξ 418,836.6",
"VOLUME24HOURTO":"$ 49,126,029.4",
"OPENDAY":"$ 118.40",
"HIGHDAY":"$ 119.29",
"LOWDAY":"$ 114.48",
"OPEN24HOUR":"$ 117.99",
"HIGH24HOUR":"$ 119.50",
"LOW24HOUR":"$ 114.12"
}
}
}
I need to generate output as below - Separate record for each symbol:
Mapping - each Currency NODE - is added as "Sym" field e.g. "ETH" Node is now "Sym" : "ETH";
rest of the fields are straight move from innermost node "USD"
{
"Sym":"ETH",
"PRICE":"$ 117.74",
"LASTTRADEID":"44473885",
"VOLUMEDAY":"Ξ 340,510.0",
"VOLUMEDAYTO":"$ 39,874,960.0",
"VOLUME24HOUR":"Ξ 418,836.6"
}
Code being used :
import com.crypto.cryptocompare.api.CryptoCompareApi
import com.google.gson.Gson
import com.google.gson.GsonBuilder;
object cryptoComapreMultiSCryptoPriceGson extends App{
val gson = new Gson()
val api = new CryptoCompareApi();
//val response = api.priceMulti("ETH,DASH","BTC,USD,EUR", new Nothing() {})
val m = new java.util.LinkedHashMap[String,Object]
m.put("extraParams", "TestProject")
val response = api.priceMultiFull( //to get priceMultiFull
"ETH,DASH,BTC",
"USD",
m)
//val jsonRec = gson.toJsonTree(response)
println(response.get("DISPLAY"))
}
Any pointers or help?

Related

How to parse a application/x-www-form-urlencoded with an associative array?

I'm trying to parse the following body:
event=invoice.created&data%5Bid%5D=1757E1D7FD5E410A9C563024250015BF&
data%5Bstatus%5D=pending&data%5Baccount_id%5D=70CA234077134ED0BF2E0E46B0EDC36F&
data%5Bsubscription_id%5D=F4115E5E28AE4CCA941FCCCCCABE9A0A
Which translates to:
event = invoice.created
data[id] = 1757E1D7FD5E410A9C563024250015BF
data[status] = pending
data[account_id] = 70CA234077134ED0BF2E0E46B0EDC36F
data[subscription_id] = F4115E5E28AE4CCA941FCCCCCABE9A0A
Code:
#PostMapping(consumes = [MediaType.APPLICATION_FORM_URLENCODED_VALUE])
fun cb(event: SubscriptionRenewed)
{
println(event)
}
data class SubscriptionRenewed(
val event: String,
val data: Data
)
data class Data(
val id: String,
val status: String,
val account_id: String,
val subscription_id: String
)
Normally you just create a POJO representation of the incoming body and spring a translates it to an object.
I learned that I could add all the parameters to the function declaration as #RequestParam("data[id]") id: String, but that would make things really verbose.
The issue is with parsing data[*], ideas of how to make it work?
Edit:
I discovered that if I change val data: Data to val data: Map<String, String> = HashMap(), the associative array will be correctly inserted into the map, ideas of how to map it to an object instead?
Note: IDs/Tokens are not real. They are from a documentation snippet.
Deserialize to Map and use json serialize/deserialize to object
Initially deserialize the input to Map<String, String>
Use Json processor(like ObjectMapper or Gson) to serialize the Map constructed in the previous step
Use the json processor to deserialize the json output of previous step to a custom object.
static class Data {
private String one;
private String a;
#Override
public String toString() {
return "Data{one=" + one + ", a=" + a + "}";
}
}
public static void main(String[] args) {
String input = "{\"one\":1, \"a\":\"B\"}";
Gson gson = new GsonBuilder().create();
Map<String, String> map = gson.fromJson(input, new TypeToken<Map<String, String>>(){}.getType());
Data data = gson.fromJson(gson.toJson(map), Data.class);
System.out.println(data);
}
This is surely a round about approach and i am not aware of any optimization

Reading data from Android App using bluetooth

I have Java code to receive data in Android App via Bluetooth like the attached code
Java Code
so readMessage will equal = {\"Pin\":\"A4\",\"Value\":\"20\"},{\"Pin\":\"A5\",\"Value\":\"925\"},{\"Pin\":\"A0\",\"Value\":\"30\"}
So I want to take only the values after string \"Value\" from received data so
Can anyone suggest how to make do that?
Thanks
you can parse the readMessage with JSON format
example:
String[] pinValueArr = readMessage.split(",")
for (String pinValue : pinValueArr) {
try {
JSONObject pinValueJSON = new JSONObject(pinValue);
String pin = pinValueJSON.optString("pin", ""); // opt means if parse failed, return default value what is ""
int pin = pinValueJSON.optInt("Value", 0); // opt means if parse failed, return default value what is "0"
} catch (JSONParsedException e) {
// catch exception when parse to JSONObject failed
}
}
And if you want to manage them, you can make a List and add them all.
List<JSONObject> pinValueList = new ArrayList<JSONObject>();
for (String pinValue : pinValueArr) {
JSONObject pinValueJSON = new JSONObject(pinValue);
// ..
pinValueList.add(pinValueJSON);
}
You can use Gson to convert Json to Object.
(https://github.com/google/gson)
Create Model Class
data class PinItem(
#SerializedName("Pin")
val pin: String? = null,
#SerializedName("Value")
val value: String? = null
)
Convert your json.
val json = "[{"Pin":"A4","Value":"20"},{"Pin":"A5","Value":"925"},{"Pin":"A0","Value":"30"}]"
val result = Gson().fromJson(this, object : TypeToken<List<PinItem>>() {}.type)
So now you having list PinItem and you can get all info off it.

Sending Streaming Data as JSON in Java/Scala

I'm used to python and using the Scala Spark Streaming libraries to handle real-time Twitter streaming data. Right now, I'm able to send as a string, however, my streaming service requires JSON. Is there a way I can easily adapt my code to send as JSON dictionary instead of a String?
%scala
import scala.collection.JavaConverters._
import com.microsoft.azure.eventhubs._
import java.util.concurrent._
val namespaceName = "hubnamespace"
val eventHubName = "hubname"
val sasKeyName = "RootManageSharedAccessKey"
val sasKey = "key"
val connStr = new ConnectionStringBuilder()
.setNamespaceName(namespaceName)
.setEventHubName(eventHubName)
.setSasKeyName(sasKeyName)
.setSasKey(sasKey)
val pool = Executors.newFixedThreadPool(1)
val eventHubClient = EventHubClient.create(connStr.toString(), pool)
def sendEvent(message: String) = {
val messageData = EventData.create(message.getBytes("UTF-8"))
// CONVERT IT HERE?
eventHubClient.get().send(messageData)
System.out.println("Sent event: " + message + "\n")
}
import twitter4j._
import twitter4j.TwitterFactory
import twitter4j.Twitter
import twitter4j.conf.ConfigurationBuilder
val twitterConsumerKey = "key"
val twitterConsumerSecret = "key"
val twitterOauthAccessToken = "key"
val twitterOauthTokenSecret = "key"
val cb = new ConfigurationBuilder()
cb.setDebugEnabled(true)
.setOAuthConsumerKey(twitterConsumerKey)
.setOAuthConsumerSecret(twitterConsumerSecret)
.setOAuthAccessToken(twitterOauthAccessToken)
.setOAuthAccessTokenSecret(twitterOauthTokenSecret)
val twitterFactory = new TwitterFactory(cb.build())
val twitter = twitterFactory.getInstance()
val query = new Query(" #happynewyear ")
query.setCount(100)
query.lang("en")
var finished = false
while (!finished) {
val result = twitter.search(query)
val statuses = result.getTweets()
var lowestStatusId = Long.MaxValue
for (status <- statuses.asScala) {
if(!status.isRetweet()){
sendEvent(status.getText())
}
lowestStatusId = Math.min(status.getId(), lowestStatusId)
Thread.sleep(2000)
}
query.setMaxId(lowestStatusId - 1)
}
eventHubClient.get().close()
Scala has no native way to convert string to Json, you'll need to use an external library. I recommend using Jackson. If you use gradle you can add a dependency like this: compile("com.fasterxml.jackson.module:jackson-module-scala_2.12"). (Use appropriate scala version)
Then, you can simply convert your data object to JSON like this:
val mapper = new ObjectMapper() with ScalaObjectMapper
mapper.registerModule(DefaultScalaModule)
val json = valueToTree(messageData)
I'd strongly recommend you put your effort in Jackson, you'll need it a lot if you work with JSON.

Parsing JSON array

I'm using GSON for parsing JSON response.
Unfortunately the WebApi on the server has quite untypical JSON objects.
I need to parse Attachments array from this JSON (there can be more attachments):
{"htmlMessage":"text","Attachments":{"8216096_0":{"content":null,"filename":"plk.jpg","contentType":"image/jpeg","contentDisposition":"attachment","size":86070}}}
Where 8216096_0 is attachments id.
I can't do it with Gson (or I don't know how) so I'm trying to do it with JSONObjects:
// parse attachments
JSONObject attachmentsJson = result.getJSONObject("Attachments");
Then I have one JSONObject with an array of attachments, but I don't know how to get them to the ArrayList from JSONObject because the key value isn't static but generated id..
Thank you
//EDIT:
Thanks to all guys for helping! My final solution looks like this especially thanks to #Jessie A. Morris and his final answer!
List<AttachmentModel> attachmentsList = new ArrayList<AttachmentModel>();
for( Map.Entry<String, JsonElement> attachment : attachments.entrySet()) {
AttachmentModel attachmentModel = new AttachmentModel();
attachmentModel = gson.fromJson(attachment.getValue().getAsJsonObject().toString(), AttachmentModel.class);;
attachmentModel.setmUid(attachment.getKey());
attachmentsList.add(attachmentModel);
}
Okay, I've changed my example a little bit and am certain that this does work correctly (I just tested it):
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Created by jessie on 14-07-09.
*/
public class TestGson {
private static String JSON = "{\"htmlMessage\":\"text\",\"Attachments\":{\"8216096_0\":{\"content\":null,\"filename\":\"plk.jpg\",\"contentType\":\"image/jpeg\",\"contentDisposition\":\"attachment\",\"size\":86070}}}\n";
public static void main(String[] args) {
JsonObject json = new JsonParser().parse(JSON).getAsJsonObject();
JsonObject attachments = json.getAsJsonObject("Attachments");
List<JsonObject> attachmentsList = new ArrayList<JsonObject>();
for( Map.Entry<String, JsonElement> attachment : attachments.entrySet()) {
attachmentsList.add(attachment.getValue().getAsJsonObject());
}
System.out.println("attachmentsList at the end? " + attachmentsList);
}
}
I'm not completely sure if this really works:
final Map<String,JSONObject> attachmentsJson = (Map<String,JSONObject>) jsonArray.getJSONObject("Attachments");
for(String attachmentId : attachmentsJson.keySet()) {
final JSONObject attachmentJson = attachmentsJson.get(attachmentId);
}
The "Attachments" obj in your example is not an array.
Json arrays are denoted by [....].
"Attachments" is a Json object holding an inner object called "8216096_0".
so to get the inner values do as follows:
JSONObject attachmentsJson = result.getJSONObject("Attachments");
JSONObject inner = attachmentsJson.getJSONObject("8216096_0");
// and interrogate the inner obj:
String content = inner.getString("content");
String filename = inner.getString("filename");
Finally, and for example sake, I will add the code for processing a (real) Json array:
{"htmlMessage":"text",
"Attachments":[{"8216096_0":{"content":null,"filename":"plk.jpg","contentType":"image/jpeg",
"contentDisposition":"attachment","size":86070}},
{"8216096_1":{"content":null,"filename":"plk.jpg","contentType":"image/jpeg",
"contentDisposition":"attachment","size":86070}},
]
}
It will go like this:
JSONArray attachmentsJson = result.getJSONObject("Attachments");
int len = attachmentsJson.length();
for (int i = 0; i < len; i++) {
JSONObject elem = attachmentsJson.getJSONObject(i); // <------ get array element
JSONObject inner = elem.getJSONObject("8216096_0");
// and interrogate the inner obj:
String content = inner.getString("content");
String filename = inner.getString("filename");
}
..Or similar, depending on your Json's exact format.

How to deserialize a JSON file into an ArrayList with nested classes?

I have this Java class:
class A {
private B b;
class B {
private String a;
//getter + setter
}
}
This is the content of JSON file:
[{"b" : {"a": "Hello!"}},
{"b" : {"a": "Hi!"}},
{"b" : {"a": "Hello2!"}}]
I want to deserialize my JSON file into an ArrayList<A> with the nested class inside.
How can I do this?
You can simply achieve this with Gson.
package stackoverflow.questions.q18932252;
import java.lang.reflect.Type;
import java.util.*;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class Q18932252 {
public static void main(String[] args){
String json = "[{\"b\" : {\"a\": \"Hello!\"}}, {\"b\" : {\"a\": \"Hi!\"}}, {\"b\" : {\"a\": \"Hello2!\"}}]";
Type listOfA = new TypeToken<List<A>>() {}.getType();
Gson g = new Gson();
ArrayList<A> result = g.fromJson(json, listOfA);
System.out.println(result);
}
}
With this result (I have added standard toString methods):
[A [b=B [a=Hello!]], A [b=B [a=Hi!]], A [b=B [a=Hello2!]]]
Since you are asking about a JSON file, ie a text file that contains a JSON string, please make reference to How to create a Java String from the contents of a file question for loading a file into a string.
Refer to this post as per the information provided in the question this should solve your problem Json parsing with Gson with data and arrays
Using gson:
Gson gson = new Gson();
String json = "[{\"b\" : {\"a\": \"Hello!\"}}, {\"b\" : {\"a\": \"Hi!\"}}, {\"b\" : {\"a\": \"Hello2!\"}}]";
A[] arrA = new A[0];
System.out.println(Arrays.toString(gson.fromJson(json, arrA.getClass())));

Categories

Resources