Storing JsonObjects in an ArrayList in Java - java

I am trying to store a multiple JsonObjects in ArrayList to parse and display in tableview at later stage.
for some odd reason I can't add objects to the list.
I am using javax.json
Here is my Try statement:
try {
JsonReader jsonReader = Json.creatReader(new StringReader(test));
JsonObject obj = jsonReader.readObject();
jsonReader.close();
key = obj.getString("key"); // this works with no issue
ArrayList<JsonObject> jsonList = new ArrayList<>();
jsonList.add(obj); // everything hangs with no errors when I try to do this
}
debugger shows jsonList size 0 obj size 3 for this line
jsonList.add(obj);
if I commented these lines everything works as expected
ArrayList<JsonObject> jsonList = new ArrayList<>();
jsonList.add(obj);
when they are not commented I am getting catch final throwable (be sure to set the state after the cause of failure.

Related

Java: How to go about return values in a try-catch?

I am somewhat in doubt about how to go about returning a value in a catch-block, when I really don't want the catch-block to return a value at all.
I am trying to make a java class 'User', that has a method for creating a user account and saving it to a json file, like so:
private void saveAsJson() {
JSONObject newUser = new JSONObject();
newUser.put("name", this.name);
newUser.put("lastName", this.lastName);
newUser.put("password", this.password);
System.out.println(newUser);
try {
File jsonFile = new File("./data/Account.json");
fileIsEmpty(jsonFile); //void method checking if file is empty or already contains data.
getJsonArray(jsonFile);//method that should parse the contents of the jsonfile to a JSONArray.
//More code...
///
...
private JSONArray getJsonArray(File sourceFile) {
try {
FileReader fr = new FileReader(sourceFile);
JSONTokener tk = new JSONTokener(fr);
JSONObject jsonObj = new JSONObject(tk);
JSONArray jsonArr = jsonObj.getJSONArray("Accounts");
return jsonArr;
} catch (Exception e) {
System.out.println("Unable to read accounts in getJsonArray.");
return *what to return??*;
}
}
The Method JSONArray is simply meant to read the json file, and return the array. The FileReader class demands that I use a try-catch, in case an exception happens while trying to read the file.
However, when that exception would happen, I don't want the method to return anything at all. The method is already called in a try-block, so I would want this parent try-block to handle the exception, in stead of carrying on with a return value from the method.
How should I go about this. What sort of value should I return? Something like JSONArray fakeArray = new JSONArray(); return fakeArray;? What happens when that value is returned, does saveAsJson() carry on with that empty array, and mess up the structure of my json file?
To be clear: I do understand that and why there must be a return value. The method getJsonArray simply expects a JSONArray to be returned. I do not know how to best handle this.
Don't catch the Exception. Declare that the method throws instead and have the caller of the method catch it.
// It's better to declare the specific type of the Exception instead of bare Exception
private JSONArray getJsonArray(File sourceFile) throws Exception {
FileReader fr = new FileReader(sourceFile);
JSONTokener tk = new JSONTokener(fr);
JSONObject jsonObj = new JSONObject(tk);
JSONArray jsonArr = jsonObj.getJSONArray("Accounts");
return jsonArr;
}

JSON pointer builder breaks when array is put() in jsonObject

I'm learning how to use JSON in java and tried building and reading JSON and found this.
int array[] = {1,2,3,4,5};
JSONObject obj = new JSONObject();
obj.put("putArray", array);
obj.append("appendArray", array);
JSONPointer pointer = JSONPointer.builder()
.append("putArray")
.build();
System.out.print(pointer.queryFrom(obj));
When I append "appendArray" to the JSON pointer it outputs the expected [[1,2,3,4,5]]
But if I append the put array I get [I#6ce253f1
I tried using JSONArray but the problem occured again if you append the array index 0 to the pointer
JSONArray jArray = new JSONArray();
jArray.put(array);
obj.put("array1", jArray);
obj.append("array2", jArray);
JSONPointer pointer = JSONPointer.builder()
.append("array1")
.append(0)
.build();
System.out.print(pointer.queryFrom(obj));
I know there are better ways to parse through JSON but I don't know what is happening. Why am I getting this weird result? What does put() vs append() change where it causes this result?

Avoiding OutOfMemoryError

I have code in which I am given a large JSON string (could be anywhere from 50MB to 250MB) that is an array of JSON objects to be parsed and sanitized then serialized to a file. Everything was going fine with 50MB JSON strings but when the string gets over a hundred or so MB my app crashes with OutOfMemoryError. I know I can increase the size of the heap but would like to avoid doing so if possible. I have included some thoughts I have been having recently. I tried moving try blocks around a little bit to no avail.
1) I suspect there is some way to do this with streams but I have no idea how to stream the result String (which is a json array string of json objects) one JSON object at a time.
2) Since result is a Java string, it is immutable. How can we consume this string and get it out of memory ASAP?
3) Would cleanedResult be better to instantiate a new object each time rather than just assign the same object something different each time?
4) At the end of the for loop shouldn't there only be roughly 2x memory used as before the loop as now json stringbuilder variable contains the same memory as the result string which should be the two largest variables in memory?
I have included the code below.
String result = getLargeJSONString(...); // function that gives me a large JSON string which is an array of JSON objects
StringBuilder json = new StringBuilder(); // to hold final JSON values to write to file
// try to parse said large JSON String
JSONArray results = new JSONArray();
try {
results = new JSONArray(result);
} catch (JSONException j) {
j.printStackTrace();
}
// do json sanitation on each object and then append to stringbuilder
// note the final result should be a string with a JSON object on each newline
JSONObject cleanedResult = new JSONObject();
for (int i = 0; i < results.length(); i++) {
try {
cleanedResult = JSONSanitizer.sanitize((JSONObject) results.get(i));
} catch (JSONException j) {
cleanedResult = new JSONObject();
}
json.append(cleanedResult.toString());
json.append('\n');
}
// write built string to file
try {
Files.write(Paths.get("../file.json"), json.toString().getBytes());
} catch (IOException i) {
System.out.println(i);
}
Of corse you should prefere streaming over contiguous memory allocation (String, StringBuilder, arrays and so) to process large amounts of data. So your best chance is to use a streaming JSON parser/serializer.
However, you should first try to optimize your code through several easy-gain fixes:
One: If you really need to store the result before wrinting it to a file, pre-size the StringBuilder to the estimated maximum final size it will have, so it won't need to be resized on every execution of append. For example, like this:
StringBuilder json = new StringBuilder(result.length());
You'd better even take in account an extra size for the newline characters. For example, oversizing 5%:
StringBuilder json = new StringBuilder((int)(1.05d*result.length()));
Two: If you just need to write the result out to a file, do not even store it into a StringBuilder:
String result = getLargeJSONString(...);
JSONArray results = new JSONArray(result);
try(Writer output=new OutputStreamWriter(new FileOutputStream(outputFile), "UTF8")) {
for (int i = 0; i < results.length(); i++) {
JSONObject cleanedResult = JSONSanitizer.sanitize((JSONObject) results.get(i));
output.write(cleanedResult.toString());
output.write('\n');
}
}

getString not working for JSON key

I'm learning how to work with JSON's in java and I'm having a problem using getString for one of my keys. My code is here:
public static void getJSON(String matchID){
String s = "";
String test = "{\"employees\":[{\"firstName\":\"John\", \"lastName\":\"Doe\"}]}";
try {
JSONObject hi = new JSONObject(test);
JSONArray stuff = hi.getJSONArray("employees");
String[] items = new String[stuff.length()];
items[0] = stuff.getString("firstName");
} catch (JSONException e) {
e.printStackTrace();
}
}
The "getString" is underlined in red, and the "The method getString(int) in the type JSONArray is not applicable for the arguments (String)" I was following an answer to another question word for word almost, and this happens, any advice? Thanks!
EDIT:
I need to get the specifics by name ie. "firstName" because I will be working with thousands of JSONs that each have hundreds of lines.
You need to get the JSOnObject first from the JSONArray(stuff) before you can call getString().
if you want to get the first element in the jsonarray and get its string this is how you would do it
JsonObject obj = stuff.getJsonObject(0);
String name = obj.getString("firstname");
So I figured out my problem, I didn't realize I had an JSONObject first, my apologies. Fixed like this:
JSONObject hi = new JSONObject(test);
JSONArray stuff = hi.getJSONArray("employees");
JSONObject name = stuff.getJSONObject(0);
String[] items = new String[hi.length()];
items[0]=name.getString("firstName");
System.out.println(items[0]);
you can try the simplest way to Parse in JSON
JSONParser parser=new JSONParser();
String s = "{\"employees\":[{\"firstName\":\"John\", \"lastName\":\"Doe\"}]}";
try{
Object obj = parser.parse(s);
JSONArray array = (JSONArray)obj;
System.out.println(array.get(1));
}catch(ParseException pe){
}

how do i add String array to JSON

I am currently writing some code in a servlet that gets data from the database and returns it to the client. What I am having problems with is inserting the array of dates I have collected and adding them to my JSON object that I will return to the client.
Here is the code I'm trying but it keeps giving errors
dates = ClassdatesDAO.getdate(dates);
ArrayList<String> ClassDates = new ArrayList<String>();
ClassDates = dates.getClassdates();
response.setContentType("application/json");
JSONObject Dates = new JSONObject();
Dates.put("dates", new JSONArray(ClassDates));
In my IDE I get this error over the ClassDates in the JSONArray
The constructor JSONArray(ArrayList) is undefined
You are passing ArrayList instance instead of an Array. So, convert the list into an array and then pass it as an argument like this
Dates.put("dates", new JSONArray(ClassDates.toArray(new String[ClassDates.size()])));
Note : json API has a method signature accepting java.util.Collection. So, you are using some other library or older version
JSONObject Dates = new JSONObject();
JSONArray datesJSONArray = new JSONArray();
for (String date : ClassDates)
datesJSONArray.put(date);
try {
Dates.put("dates", datesJSONArray);
} catch (JSONException e) {
e.printStackTrace();
}

Categories