Reading json file and updating - java

Im trying to understand the procedure to do what the title says.
Im doing this in java with Gson dependency.
I am getting information from another service I use, in JSON format. So I want to get that info, put some additional info in there (like date/time) and use it afterwards for searching purposes.
The procedure is :
Get the JSON info (lets say "id") and add it to the JSON file you have
Add more info to that JSON file (lets say "Date and time of upload")
Finally, save that updated JSON file
So I read the file:
JsonReader reader = new JsonReader(new FileReader(filename));
Do I have now to convert it to string, and then update the string, so I can finally write it back to json?
If it doesn't exist, I create an empty file and then, can I update it with Json/Gson data? or do I have to create a Json File?
try {
File jsonFile = new File("C:\\uploads\\datasets");
if (jsonFile.createNewFile()){
System.out.println("File is created!");
}else{
System.out.println("File already exists.");
}
} catch (IOException e) {
e.printStackTrace();
}
Excuse any newbie/stupid mistakes I've probably made, I'm trying to understand JSON. Actually, the philosophy behind it.

JSON stands for JavaScript Object Notation and it's nothing more than a way to format data.
Taken from here:
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is
realized as an object, record, struct, dictionary, hash table, keyed
list, or associative array.
An ordered list of values. In most
languages, this is realized as an array, vector, list, or sequence.
To address your questions:
Get the JSON info (lets say "id") and add it to the JSON file you have
JsonReader reader = new JsonReader(new FileReader(inputFilename));
reader.beginArray();
reader.beginObject();
long id = -1;
while (reader.hasNext()) {
String value = reader.nextName();
if (value.equals("id")) {
id = reader.nextLong();
} else {
reader.skipValue();
}
reader.endObject();
reader.endArray();
Add more info to that JSON file (lets say "Date and time of upload")
This will get the format in YYYY.MM.DD-HH.MM.SS
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(Calendar.getInstance().getTime());
Finally, save that updated JSON file
Create a JsonWriter.
JsonWriter writer = new JsonWriter(new FileWriter(outputFilename));
writer.beginArray();
writer.beginObject();
writer.name("id").value(id);
writer.name("timestamp").value(timestamp);
writer.endObject();
writer.endArray();
You can read more about JsonReader and JsonWriter here and here.

Related

Write data in JSON file in right form JAVA

I have question about the form of the data input in JSON.
I save data with a button click in a json file, but the output is wrong. How can I fix this problem, so that the new dataset is after the comma?
JSONObject json = new JSONObject();
File filename = new File("dbsettings.json");
json.put("driver", textFieldDriver.getText());
json.put("url", textFieldURL.getText());
json.put("scheme", textFieldscheme.getText());
json.put("name", textFieldDBname.getText());
try {
System.out.println("Writting Data into JSONfile ...");
System.out.println(json);
FileWriter jsonFileWriter = new FileWriter(filename.getAbsoluteFile(), true);
jsonFileWriter.write(json.toJSONString());
jsonFileWriter.flush();
jsonFileWriter.close();
System.out.println("Done!");
} catch (IOException e) {
e.printStackTrace();
}
JOptionPane.showMessageDialog(
null, "Save Data successful", "Information", JOptionPane.INFORMATION_MESSAGE
);
setVisible(false);
this is my Output:
[{
"driver": "oracle.jdbc.driver.OracleDriver",
"url": "dburl1",
"scheme": "myscheme1",
"name": "mydbname1"
},{
"driver": "oracle.jdbc.driver.OracleDriver",
"url": "myurl",
"scheme": "myscheme",
"name": "mydbname"
}]{"scheme":"test3","name":"test4","driver":"test1","url":"test2"}
Pls help me!
The problem is with your FileWriter object and having the true. This means it will append to the file. If you want to correctly add JSON objects to the file I would suggest reading all of the JSON objects form the file first. Then store them in a list and append to the list any new entries from your program. When your program is done, loop the list of JSON objects collected and overwrite the file you are reading from with all the new and old JSON objects.
When program starts up, read from "dbsettings.json" and store all those JSON objects in some sort of data structure. An arraylist would work or perhaps a Hashmap if you need to find JSON objects later in your program based on some key.
Then as the program runs and you are receiving input from the user on new JSON objects just add them to your data collection. Do not write them to the file every time you get a new one. I recommend only overwriting the file with all the JSON objects in your collection when the user exits the program cleanly. That way you ensure that your data is in correct JSON form every time you start your program. The only downside is that if the program quits unexpectedly you lose all the data you entered during the run of the program.
The other less optimal solution would be to do everything up above except you do this every time you get data from the user.
//for JSON you want to output them like "[json0, json1,json2,... etc]"
FileWriter jsonFileWriter = new FileWriter(filename.getAbsoluteFile());
jsonFileWriter.write("[")
for(int i = 0; i < jsonDataStructure.size(); i++)
{
jsonFileWriter.write(jsonDataStructure.get(i).toJSONString());
if(i + 1 != jsonDataStructure.size())
jsonFileWriter.write(",");
}
jsonFileWriter.write("]");
jsonFileWriter.flush();
jsonFileWriter.close();

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.

Java JSON - gson - appending new data, malformed JSON

I am using Gson to write to and read from a file.
each time a user is created, I append a line which shows Username and ID.
I do this with the following (UserAccount being my pojo class, br is my buffered reader)::
UserAccount accountObj = new UserAccount();
FileWriter writer = new FileWriter("store.json", true);
accountObj.setUser(NewUserMethod());
accountObj.setID(NewIDMethod());
String json = gson.toJson(accountObj);
writer.write(json);
writer.close();
This makes the json file, which works - like this ::
{"USER":"noob123","ID":"99"}
When a new user does it, It will append the next line like so ::
{"USER":"noob123","ID":99}{"USER":"pro321","ID":100}
When I attempt to read this json file, I got the following error ::
"use JsonReader.setLenient(true) to accept malformed JSON at line 1, column 36"
So I understand it may be incorrect format and may need something like ::
{"ACCOUNT":{"USER":"noob123","ID":99},"ACCOUNT":{"USER":"pro321","ID":100}}
I have spent some time trying to create JSON in this format, or at least reference to the correct USER key when the matching USER name is used. Any help is greatly appreciated.
Thanks
You should use JSONArray to save this information into file. Then you can read content of file into list of UserAccount, add new object into this list.
Then you should override content of file.
E.g. :
UserAccount accountObj = new UserAccount();
accountObj.setUser(NewUserMethod());
accountObj.setID(NewIDMethod());
List<UserAccount> userAccounts = gson.fromJson(<jsonContent>, new TypeToken<List<UserAccount>>() {
}.getType());
userAccounts.add(accountObj);
String json = gson.toJson(userAccounts);
writer.write(json);
writer.close();

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.

Parse ~1 MB JSON on Android very slow

I have an approximately 1MB JSON file stored in my assets folder that I need to load in my app every time it runs. I find that the built-in JSON parser (org.json) parses the file very slowly, however once it's parsed, I can access and manipulate the data very quickly. I've counted out as many as 7 or 8 seconds from the moment I click on the app to the moment the Activity1 is brought up, but just a few milliseconds to go from Activity1 to Activity2 which depends on data processed from the data loaded in Activity1.
I'm reading the file into memory and parsing it using:
String jsonString = readFileToMemory(myFilename)
JSONArray array = new JSONArray(jsonString);
where readFileToMemory(String) looks like this:
private String readFileToMemory(String filename) {
StringBuilder data = new StringBuilder();
BufferedReader reader = null;
try {
InputStream stream = myContext.getAssets().open(filename);
reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
int result = 0;
do
{
char[] chunk = new char[512];
result = reader.read(chunk);
data.append(chunk);
}
while(result != -1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return data.toString();
}
Does anyone have any suggestions to how I can speed up the initial loading and parsing of the data? Should I perhaps mask the whole process behind a loading screen?
JSONObject -- the one from json.org, is the simplest API to use to parse JSON. However it comes with a cost -- performace. I have done extensive experiments with JSONObject, Gson and Jackson. It seems no matter what you do, JSONObject (and hence JSONArray) will be the slowest. Please switch to Jackson or Gson.
Here is the relative performance of the two
(fastest) Jackson > Gson >> JSONObject (slowest)
Refer:
- Jackson
- Gson
You should make an SQLite table to store the data and move it from JSON to SQL the first time the app runs. As an added benefit, this makes the data easier to search through and makes it possible for you to modify the data from within the app.

Categories