Loop through json file appending key value to List - java

I am trying to loop through a JSON file and append the value each time to patientList. So far I believe I have done the hard part, however the simplest part seems to be taking a lot of time, that is appending the values to patientList. My getJsonFile method gets the path of the JSON file. The format of the JSON file is below. I am able to print jsonArray so I know I am good up to that point, but lost after that.
Json file.
[{"patient":1},{"patient":2},{"patient":3},{"patient":4},{"patient":5},{"patient":6},{"patient":7},{"patient":8},{"patient":9}]
getJsonFile method.
private List<Integer> getJsonFile(String path)
{
List<Integer> patientList = new ArrayList<>();
try (FileReader reader = new FileReader(path))
{
JSONParser jsonParser = new JSONParser();
JSONArray jsonArray = (JSONArray)jsonParser.parse(reader);
System.out.println(jsonArray);
// Update patientList
for (int i = 0; i < jsonArray.size(); i++ )
{
patientList.add(jsonArray(i));
}
}
catch(IOException | ParseException | NullPointerException e)
{
e.printStackTrace();
}
return patientList;
}

Your JSONArray contains objects: {"patient":1}
So you could not add patientList.add(jsonArray(i));
You have to access the int value inside that object:
JSONObject patient = jsonArray.getJsonObject(i);
patientList.add(patient.getInt("patient");
Edit
Well. You are using the simple-json library with quite limit feature and outdated. In this case you have to cast the data yourself:
JSONObject patient = (JSONObject)jsonArray.get(i);
patientList.add((Integer)patient.get("patient");
I recommend you remove this lib and use existing JSON feature of Java. If you want more advance feature, Jackson/GSon is the library to use.

Related

Character encoding of parsed strings is wrong only after building jar

I am writing a program that generates PDF files of printable exams. I have all the exam questions stored in a JSON file. The catch is that the exam is in Czech, so there are many special characters (specifically ěščřžýáíé). When I run the program in Idea, it works perfectly - the output is exactly as it is supposed to be.
But when I build the jar executable, the generated files have chunks of wrong encoded text. Specifically anything that went through the JSON parser. Everything hard coded like headers etc. is encoded properly, so the mistake must be in the parser.
The JSON input file is encoded in UTF-8.
I use these two methods to parse the JSON file.
private static Category[] parseJSON(){
JSONParser jsonParser = new JSONParser();
Category[] categories = new Category[0];
try (FileReader reader = new FileReader("otazky.json")){
// Read JSON file
Object obj = jsonParser.parse(reader);
JSONArray categoryJSONList = (JSONArray) obj;
java.util.List<JSONObject> categoryList = new ArrayList<>(categoryJSONList);
categories = new Category[categoryJSONList.size()];
int i = 0;
for (JSONObject category : categoryList) {
categories[i] = parseCategoryObject(category);
i++;
}
} catch (ParseException | IOException e) {
e.printStackTrace();
}
return categories;
}
private static Category parseCategoryObject(JSONObject category) {
String categoryName = (String) category.get("name");
int generateCount = (int) (long) category.get("generateCount");
JSONArray questionsJSONArray = (JSONArray) category.get("questions");
java.util.List<JSONObject> questionJSONList = new ArrayList<>(questionsJSONArray);
Question[] questions = new Question[questionJSONList.size()];
int j = 0;
for (JSONObject question : questionJSONList) {
JSONArray answers = (JSONArray) question.get("answers");
String s = (String) question.get("question");
String[] a = new String[answers.size()];
for (int i = 0; i < answers.size(); i++) {
a[i] = answers.get(i).toString();
}
int c = (int) (long) question.get("correct");
Question q = new Question(s, a, c);
questions[j] = q;
j++;
}
return new Category(categoryName, questions, generateCount);
}
The output looks like this:
...
Právnà norma:
a) je obecnÄ› závaznĂ© pravidlo chovánĂ, kterĂ© nemusĂ mĂt urÄŤitou formu,
b) nemĹŻĹľe bĂ˝t součástĂ právnĂho pĹ™edpisu,
...
While I would need it to look like this:
...
Právní norma:
a) je obecně závazné pravidlo chování, které nemusí mít určitou formu,
b) nemůže být součástí právního předpisu,
...
Benjamin Urquhart suggested that I try using InputStringReader and FileInputStream instead of FileReader to read the file, because with FileReader you cannot specify the encoding (system default is used). I find those two methods hard to use, but I found an alternative - Files.readAllLines, which is fairly easy to use, and it worked.

How to create JSON object without using String?

I want to create an android application that uses an API to show some information on a listview. The problem I am facing is that the json file that I want to download is too big for String the object. My instructor told me that Android Studio somehow limited the size of the String. I get the error "constant string too long".
Is it possible for me to download that information as a json file (it is .geojson actually) and store it somewhere in the disk (actually I can download the file), and then parse it without using any String object by reading it from the file itself. OR Can you suggest another way of doing it since I am new in programming?
The solution I found is that using simple JSON simple library in my project.
You can get it from here.
After I downloaded the JSON file to the storage, I parsed it by using the code below:
JSONParser parser = new JSONParser();
Object obj = null;
try {
obj = parser.parse(new FileReader(directory of the folder + "/fileName.extension"));
} catch (IOException e) {
e.printStackTrace();
} catch (org.json.simple.parser.ParseException e) {
e.printStackTrace();
}
JSONObject jsonObject = (JSONObject) obj;
Now you can use jsonObject as how you want.

Gson, creating a simple JsonArray of JsonObjects

I'm trying to build a JsonArray of JsonObjects using gson.
Each JsonObject will take the following format,
{"image":"name1"}
{"image":"name2"}
and so on.
I have a string array of the names ("name1","name2",...)
I cannot convert string array directly in to a JsonArray. I'm trying to create JsonObjects iteratively and add it to a JsonArray.
JsonObject innerObject;
JsonArray jArray = new JsonArray();
for(int i = 0; i<names.length; i++)
{
innerObject = new JsonObject();
innerObject.addProperty("image",names[i]);
jArray.add(innerObject);
}
But as I understand, add method in JsonArray takes a JsonElement and here I'm giving a JsonObject. I couldn't find a way to convert JsonObject to JsonElement.
The whole point of using gson will be gone when I do this. Is there a better way?
First, create a class that represents a single json object, e.g.:
class MyObject {
private String image;
public MyObject(String name) { image = name; }
}
Gson will use the class' variable names to determine what property names to use.
Then create an array or list of these using the data you have available, e.g.
ArrayList<MyObject> allItems = new ArrayList<>();
allItems.add(new MyObject("name1"));
allItems.add(new MyObject("name2"));
allItems.add(new MyObject("name3"));
Finally, to serialize to Json, do:
String json = new Gson().toJson(allItems);
And to get the data back from json to an array:
MyObject[] items = new Gson().fromJson(json, MyObject[].class);
For simple (de)serialization, there is no need to be dealing directly with Json classes.
If you are going to use GSON use it like this to convert to object
List<Image>images = new Gson().fromJson(json, Image[].class);
To get json string
String json = new Gson().toJson(images);
That's the point of gson you should not manipulate the data with loops and stuff. You need to take advantage of its powerful model parsing.
Maybe too late but... There is a way to do without creating a new class if you dont need it:
import com.google.gson.JsonObject;
import com.google.gson.JsonArray
...
...
JsonArray jobj = new JsonArray();
String[] names = new String[]{"name1","name2","name3"};
for(String name : names) {
JsonObject item = new JsonObject();
item.addProperty("name",name);
jobj.add(item);
}
System.out.println(jobj.toString());// ;)

How to change some values in a .JSON file and then write it back while keeping the JSON formatting ? (Java)

The JSON example file consists of:
{
"1st_key": "value1",
"2nd_key": "value2",
"object_keys": {
"obj_1st": "value1",
"obj_2nd": "value2",
"obj_3rd": "value3",
}
}
I read the JSON file into a String with this StringBuilder method, in order to add the newlines into the string itself. So the String looks exactly like the JSON file above.
public String getJsonContent(String fileName) {
StringBuilder result = new StringBuilder("");
File file = new File(fileName);
try (Scanner scanner = new Scanner(file)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
result.append(line).append("\n");
}
scanner.close();
} catch (IOException e) {
e.printStackTrace();
}
return result.toString();
}
Then I translate the JSON file into an Object using MongoDB API (with DBObject, BasicDBObject and util.JSON) and I call out the Object section I need to change, which is 'object_keys':
File jsonFile = new File(C:\\example.json);
String jsonString = getJsonContent(jsonFile.getAbsolutePath());
DBObject jsonObject = (DBObject)JSON.parse(jsonString);
BasicDBObject objectKeys = (BasicDBObject) jsonObject.get("object_keys");
Now I can write new values into the Object using the PUT method like this:
objectKeys.put("obj_1st","NEW_VALUE1");
objectKeys.put("obj_2nd","NEW_VALUE2");
objectKeys.put("obj_3rd","NEW_VALUE3");
! This following part not needed, check out my answer below.
After I have changed the object, I need to write it back into the json file, so I need to translate the Object into a String. There are two methods to do this, either one works.
String newJSON = jsonObject.toString();
or
String newJSON = JSON.serialize(jsonObject);
Then I write the content back into the file using PrintWriter
PrintWriter writer = new PrintWriter(C:\\example.json)
writer.print(newJSON);
writer.close();
The problem I am facing now is that the String that is written is in a single line with no formatting whatosever. Somewhere along the way it lost all the newlines. So it basically looks like this:
{"1st_key": "value1","2nd_key": "value2","object_keys": { "obj_1st": "NEW_VALUE1","obj_2nd": "NEW_VALUE2","obj_3rd": "NEW_VALUE3", }}
I need to write the JSON file back in the same format as shown in the beginning, keeping all the tabulation, spaces etc.
Is this possible somehow ?
When you want something formatted the way you said it is addressed as writing to a file in a pretty/beautiful way. For example: Output beautiful json. A quick search on google found what i believe to solve your problem.
Solution
You're going to have to use a json parser of some sort. I personally prefer org.json and would recommend it if you are manipulating the json data, but you may also like json-io which is really good for json serialization with no external dependencies.
With json-io, it's as simple as
String formattedJson = JsonWriter.formatJson(jsonObject.toString())
With org.json, you simply pass an int to the toString method.
Thanks Saraiva, I found a surprisingly simple solution by Googling around with the words 'pretty printing JSON' and used the Google GSON library. I downloaded the .jar and added it to my project in Eclipse.
These are the new imports I needed:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
Since I already had the JSON Object (jsonObject) readily available from my previous code, I only needed to add two new lines:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String newJSON = gson.toJson(jsonObject);
Now when I use writer.print(newJSON); it will write the JSON in the right format, beautifully formatted and indented.

Getting java object back from JSON

I am putting some java objects in the Json at server side
like this :
ArrayList<VisjsNode>visjsNodes = new ArrayList<VisjsNode>();
ArrayList<VisjsConnection> visjsConnections = new ArrayList<VisjsConnection>();
String jsondata = null;
org.json.JSONObject object = new org.json.JSONObject();
try {
object.put("nodes", visjsNodes);
object.put("connections", visjsConnections);
jsondata = object.toString();
Now is there a way I can get these objects back from this json (jsondata) at client side
I am doing this:
com.google.gwt.json.client.JSONValue jsonValue = JSONParser.parseStrict(jsondata);
com.google.gwt.json.client.JSONObject jsonObject = jsonValue.isObject();
jsonValue = jsonObject.get("nodes");
Now I am trying this to get ArrayList back , by doing this
ArrayList<VisjsNode>visjsNodesFromjson = jsonValue ;
But its not compiling ,it says Incompatable types...
Can you please guide how we can retrieve the Java Object back from Json ..
That's because you're using two different JsonObject class. First you use the one which comes from org.json (org.json.JsonObject) and the other is com.google.gwt.json.client.JSONObject. Nevertheless, they're named similar, they're completely different classes.

Categories