Converting a JSON payload into useful data in Java - java

Just to start off, I'm new to Java. I'm trying to make a notification system for Twitch using their API and an Arduino, and I'm currently stuck at the start pretty much. I am able to access the API and get information, but I don't know how to convert it into something useful. This is my code currently.
public class commandRun {
public static void main(String[] args) {
Process p;
try {
p = Runtime.getRuntime().exec("cmd /c curl -H \"Client-ID: clientID\" -X GET \"https://api.twitch.tv/helix/users/follows?first=1&to_id=channelID\n");
p.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String twitchFollower;
while((twitchFollower = reader.readLine()) != null) {
System.out.println(twitchFollower);
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This returns
{
"total": 106,
"data": [
{
"from_id": "followerID",
"from_name": "follower",
"to_id": "channelid",
"to_name": "channel",
"followed_at": "2019-10-06T21:03:03Z"
}
],
"pagination": {
"cursor": "dontknowifthisissensitiveinfo"
}
}
I want to be able to take specific info out of string such as the followers' name.

There are many JSON libraries can achieve this as jrook's comment.
And following sample code shows how the most 2 popular libraries - Jackson and Gson - get the value of specific field. (I assumed that the key of follower's name is from_name.)
// Jackson
ObjectMapper mapper = new ObjectMapper();
String followerName = mapper.readTree(jsonStr)
.get("data")
.get(0)
.get("from_name")
.asText();
System.out.println(followerName);
// Gson
followerName = new JsonParser().parse(jsonStr)
.getAsJsonObject()
.get("data")
.getAsJsonArray()
.get(0)
.getAsJsonObject()
.get("from_name")
.getAsString();
System.out.println(followerName);
Console output:
follower
follower

Related

How to Read Large Json File in chunks

I am using below JSON format:
[{object1},{object2},{object3}...]
I am reading a JSON file object wise means one by one (object by object) and my below code working fine.
I want to read it in chunks(at a time 10 objects). I have tried a lot but I am not getting any solution (without using Spring Batch). Can anybody please help me how to read in chunks
#Component
public class PdpiRunner3 implements CommandLineRunner {
#Override
public void run(String... args) throws Exception {
try {
JsonReader jsonReader = new JsonReader(new InputStreamReader(new ClassPathResource("/json/trades2.json").getInputStream(),StandardCharsets.UTF_8));
Gson gson = new GsonBuilder().create();
jsonReader.beginArray();
while (jsonReader.hasNext()) { // next json array element
PDPIfiles json = gson.fromJson(jsonReader, PDPIfiles.class);
if (json != null) {
System.out.println(json);
}
}
jsonReader.endArray();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Is it possible to read json element In Chunk without spring Batch pleas help ?

Java : 64 based string decode / parse failed

I am trying to convert this 64 based encoded JSON string and convert received JSON into POJO using flexjson API.
First try block, converts direct JSON as string into object which is success. This string is decoded using online tool.
Now second try block, try to convert 64 based string into an object in a similar way but converting the 64based string on the run which is throwing exception flexjson.JSONException: Expected a ',' or ']' at character 10
try {
AsyncResponseDO asyncResponseDO = new JSONDeserializer<AsyncResponseDO>().deserialize("{\"relatesTo\":\"7_Sept2017_IF01\"}", AsyncResponseDO.class);
System.out.println(asyncResponseDO.getRelatesTo());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
AsyncResponseDO asyncResponseDO = new JSONDeserializer<AsyncResponseDO>().deserialize(Base64.decodeBase64("eyJyZWxhdGVzVG8iOiI3X1NlcHQyMDE3X0lGMDEifQ==".getBytes()).toString(), AsyncResponseDO.class);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
POJO class :
public class AsyncResponseDO {
private String relatesTo;
public String getRelatesTo() {
return relatesTo;
}
public void setRelatesTo(String relatesTo) {
this.relatesTo = relatesTo;
}
}
new String(Base64.decodeBase64("eyJyZWxhdGVzVG8iOiI3X1NlcHQyMDE3‌X0lGMDEifQ==".getByt‌es()));
This will convert into a proper string.
I referred to https://www.mkyong.com/java/how-do-convert-byte-array-to-string-in-java/

JMeter does not execute Java code correctly if it's ran as .jar file from command line

I'm designing JMeter scenario which implies executing a certain .jar file via OS Process Sampler element. My Java code has while loop which basically checks a certain mailbox for a letter with a certain subject. Loop waits until finds one (emails are always delivered with roughly 3 minutes delay), parses it and writes some data to .txt file.
If I run this .jar directly from cmd then the code works as expected. But if I run it via JMeter OS Process Sampler then it never creates a file for me. I do see that email is delivered to inbox, so expect it to be parsed and .txt created.
At first I suspected that JMeter finishes Java scenario without waiting for while loop to execute. Then I put OS Process Sampler in a separate Thread and added a huge delay for this thread in order to wait and make 100% sure that email is delivered and Java only need to parse it but it does not help.
View Results Tree never shows any errors.
Here is my OS Process Sampler: https://www.screencast.com/t/LomYGShJHAkS
This is what I execute via cmd and it works as expected: java -jar mailosaurJavaRun.jar email533.druzey1a#mailosaur.in
And here is my code (it does not looks good but it works):
public class Run {
public static void main(String[] args) {
MailosaurHelper ms = new MailosaurHelper();
String arg1 = ms.getFirstLinkInEmail(args[0]);
BufferedWriter output = null;
try {
File file = new File("url.txt");
output = new BufferedWriter(new FileWriter(file));
output.write(arg1);
} catch ( IOException e ) {
e.printStackTrace();
} finally {
if ( output != null ) {
try {
output.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
public class MailosaurHelper {
protected final String API_KEY = "b3e4d2b193b5eb2";
protected final String MAILBOX_ID = "d1uzey1a";
public MailboxApi getEmailBox() {
return new MailboxApi(MAILBOX_ID, API_KEY);
}
public String getFirstLinkInEmail(String email) {
MailosaurHelper ms = new MailosaurHelper();
String link = "";
if (link.equals("") || link.isEmpty()) {
try {
Thread.sleep(3000);
link = ms.getAllEmailsByReceipent(email)[0].html.links[0]
.toString();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return link;
}
public Email[] getAllEmailsByReceipent(String recepient) {
try {
int ifArrayIsEmpty = getEmailBox().getEmailsByRecipient(recepient).length;
while (ifArrayIsEmpty == 0) {
try {
Thread.sleep(3000);
ifArrayIsEmpty = getEmailBox().getEmailsByRecipient(
recepient).length;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (MailosaurException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Email[] listOfEmails = null;
try {
listOfEmails = getEmailBox().getEmailsByRecipient(recepient);
} catch (MailosaurException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return listOfEmails;
}
The bottom line is that I need to parse Mailosaur email, retrieve URL from it and use it further. Any other suggestion on how to do that using Jmeter/Java/Mailosaur are appreciated.
You don't need cmd in here, but if you're adamant to stick with it - use /C key when you call it.
Then, are your sure you're looking for your file in the right place?
According to documentation:
By default the classes in the java.io package always resolve relative
pathnames against the current user directory. This directory is named
by the system property user.dir, and is typically the directory in
which the Java virtual machine was invoked.
Check it thoroughly, BTW - you should see it in your sampler result.

try catch code reading JSON file Android

having some serious problem when trying to read a local JSON file. I've looked everywhere for many days now and the best and farthest I could get was copying from Faizan's answer.
Reading a json file in Android
How come that Android Studio doesn't let me generate the second try-catch code block here?
Help and advice are very much appreciated!!
This is My code
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getAssets().open("names.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
String jsonString = loadJSONFromAsset();
try {
JSONObject json = new JSONObject(jsonString);
JSONObject jObject = json.getJSONObject("female");
JSONObject jObject2 = jObject.getJSONObject("adult");
String name = jObject2.toString();
}
catch (Exception e) {
e.printStackTrace();
}
}
How come that Android Studio doesn't let me generate the second
try-catch code block here?
Simply, because your code is not inside a method.
Doing something like below should solve the error.
public void someMethodIdentifier(){ // doesn't have to be void return type, you know better than me what type you want to return.
String jsonString = loadJSONFromAsset();
try {
JSONObject json = new JSONObject(jsonString);
JSONObject jObject = json.getJSONObject("female");
JSONObject jObject2 = jObject.getJSONObject("adult");
String name = jObject2.toString();
}
catch (Exception e) {
e.printStackTrace();
}
}
Note - from the looks of the statements that's contained within the try block I think you intended to return some data? if that's the case just replace the void return type with the appropriate return type and return that data.

how to deserialize a list of emails on a xml file in Java?

I have an application that will spit out a XML file with the contents of a email. This XML file will be parsed by a different application and will deliver the email. The part where the application sends the email is validated.
The method that actually sends the email is this:
public void sendEmail(List<String> toRecipients, List<String> ccRecipients, List<String> bccRecipients, String subject, String body) {
// code..
}
The test email I'm trying to send should come from this XML file:
<?xml version="1.0" encoding="utf-8"?>
<email>
<to>
<recipient>user1#somecompany.com</recipient>
<recipient>user2#somecompany.com</recipient>
</to>
<cc>
<recipient>user3#somecompany.com</recipient>
</cc>
<bcc>
<recipient>user5#somecompany.com</recipient>
</bcc>
<subject>test ABC </subject>
<body><h1>test XYZ</h1></body>
</email>
I'm using the XStream library, and my problem resides on parsing a list of . I've tried a few different approaches, but am stuck. The XML parsing method is:
private void parseXmlFile(String xmlFilePath) {
XStream xstream = new XStream(new DomDriver());
xstream.alias("email", EmailPojo.class);
xstream.alias("recipient", Recipient.class);
xstream.alias("to", To.class);
xstream.alias("cc", Cc.class);
xstream.alias("bcc", Bcc.class);
xstream.addImplicitCollection(To.class, "to", "to", Recipient.class);
// xstream.addImplicitCollection(To.class, "to");
// xstream.addImplicitCollection(Cc.class, "cc");
// xstream.addImplicitCollection(Bcc.class, "bcc");
EmailPojo emailPojo = new EmailPojo();
StringBuilder sb = new StringBuilder();
try {
// filename is filepath string
BufferedReader br = new BufferedReader(new FileReader(new File(xmlFilePath)));
String line;
while ((line = br.readLine()) != null) {
sb.append(line.trim());
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
List<EmailPojo> emailPojoList = new ArrayList<EmailPojo>();
try {
emailPojoList = (List<EmailPojo>) xstream.fromXML(sb.toString());
} catch (Exception e) {
emailPojo = null;// TODO: handle exception
}
}
THis seems straight forward enough, but I'm not able to get this going.
Wha am I missing here? What's wrong here?
Thanks in advance!
Edit: forgot the exception output:
Exception in thread "main" com.thoughtworks.xstream.InitializationException: No field "to" for implicit collection
The line:
xstream.addImplicitCollection(To.class, "to", "to", Recipient.class);
Is saying there's a collection field on the class To called to that is where the instances of Recipient should be added.
Without seeing the To class this is a guess, but I reckon the field on collection field on the class To is more likely to be called recipients which should be registered with:
xstream.addImplicitCollection(To.class, "recipients", Recipient.class);
See the JavaDoc for xstream.addImplicitCollection(Class, String, Class)

Categories