JSONWriter add a new Line - java

I want to write several JSON Objects into a txt-file. For a better view I want that each object is in a different line and there is my problem: I don't know how to add a new line or seperate these objects.
Here is my code:
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("Item", item);
builder.add("Choice 1", idchoice1);
builder.add("Choice 2", idchoice2);
builder.add("Choice 3", idchoice3);
JsonObject jo = builder.build();
try {
FileWriter fw = new FileWriter("SelectedChoice.txt", true);
JsonWriter jsonWriter = Json.createWriter(fw);
jsonWriter.writeObject(jo);
jsonWriter.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
I hope you can help me to solve my problem.
Thanks to everyone!
EDIT:
Now I have seen that this structure in my file doesn't solve my problem.
I want to splitt several JSON Strings which are saved in this txt file and my code only converts the first JSON String in a JSON Object. Here my code:
try {
FileReader fr = new FileReader("SelectedChoice.txt");
BufferedReader br = new BufferedReader(fr);
String zeile ="";
while((zeile = br.readLine())!=null) {
System.out.println(zeile);
JSONObject choice = new JSONObject(zeile);
System.out.println(choice);
}
br.close();
fr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I hope you can help me again!

You can use the pretty print option:
JsonObjectBuilder builder = Json.createObjectBuilder();
builder.add("Item", item);
builder.add("Choice 1", idchoice1);
builder.add("Choice 2", idchoice2);
builder.add("Choice 3", idchoice3);
JsonObject jo = builder.build();
try {
Map<String, Object> properties = new HashMap<>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
FileWriter fw = new FileWriter("SelectedChoice.txt", true);
JsonWriterFactory writerFactory = Json.createWriterFactory(properties);
JsonWriter jsonWriter = writerFactory.createWriter(fw);
jsonWriter.writeObject(jo);
jsonWriter.close();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}

Related

Json is not being written to file

I've taken input from editText and trying to write its text to a json file. When I execute the code, it works without any errors. But when I try to read the json file again it doesn't have the previously written objects.
I've tried using different writers like BufferedWriter, FileWriter. None of them works.
This is the writeToJsonFile method
void writeJsonFile(TextView textView) {
String json;
try {
InputStream is = context.getAssets().open("chores.json");
int size = is.available();
byte[] buffer = new byte[size];
if (is.read(buffer) == -1) {
throw new EOFException();
}
is.close();
json = new String(buffer, StandardCharsets.UTF_8);
JSONObject obj = new JSONObject(json);
JSONObject m_jArray = obj.getJSONObject("chores");
JSONArray jsonArray = m_jArray.getJSONArray(title);
JSONObject new_jobj = new JSONObject();
new_jobj.put("task", textView.getText());
new_jobj.put("isCompleted", false);
jsonArray.put(new_jobj);
File file = new File(context.getExternalFilesDir("/assets"), "chores.json");
writeJsonFile(file, obj);
Log.i("Done => ", "Written to file");
} catch (EOFException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
This function takes a file and a json object and writes the json object to the file
public static void writeJsonFile(File file, JSONObject json) throws IOException {
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(json.toString());
if (fileWriter != null) {
fileWriter.close();
}
}
I expect it to write the json string to the file, but next time I read the file again with the InputStream, It doesn't show the previously added Object.
expected chores.json
{
"chores": {
"Daily": [
{
"task": "Task 1",
"isCompleted": false
}
],
"Weekly": [
],
"Monthly": [
],
"Custom": [
]
}
}
resulting json
{
"chores": {
"Daily": [
],
"Weekly": [
],
"Monthly": [
],
"Custom": [
]
}
}
You are not writing newly created object into file: For example:
...
JSONObject new_jobj = new JSONObject();
new_jobj.put("task", textView.getText());
new_jobj.put("isCompleted", false);
jsonArray.put(new_jobj);
File file = new File(context.getExternalFilesDir("/assets"), "chores.json");
// here instead of old obj write newly created new_jobj to file.
writeJsonFile(file, new_jobj);
Log.i("Done => ", "Written to file");
...
Before that make sure you have read and write storage permisions....
Ex.
try
{
Writer output = null;
File file = new File("filePath");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
file.createNewFile();
}
output = new BufferedWriter(new FileWriter(file));
output.write(jsonObject.toString());
output.close();
} catch (Exception e) {
e.printStackTrace();
}
You can use the append property in FileWriter constructor. You can try it.
FileWriter fileWriter = new FileWriter(file,true);

Copying and appending Strings to json file in Android Studio

I have list of json files as below:
At the moment, T.json file is empty. All the other files already have some text. What I need is to create something like this:
1.At the beginning of the T.json file add sth like
{
"T": [
2.Copy text from e.g. T_Average.json and T_Easy.json to T.json file
3.At the end of T.json file add this:
]
}
So at the end of program execution I need to have in my T.json sth like:
{
"T": [
text from T_Average.json
text from T_Easy.json
]
}
So how can I add text from 1st and 3rd step to the file?
And how can I copy everything from other files to T.json file?
I have already tried some solutions like this:
try(FileWriter fw = new FileWriter("T.json", true);
BufferedWriter bw = new BufferedWriter(fw);
PrintWriter out = new PrintWriter(bw))
{
out.println("the text");
out.println("more text");
} catch (IOException e) {
//exception handling left as an exercise for the reader
}
or like this one:
try {
String data = " This is new content";
File file = new File(FILENAME);
if (!file.exists()) {
file.createNewFile();
}
fw = new FileWriter(file.getAbsoluteFile(), true);
bw = new BufferedWriter(fw);
bw.write(data);
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
but all the time, after line with fw = new FileWriter() it was jumping right to the catch clause.
So one more time:
How can I add text from 1st and 3rd step to the file?
And how can I copy everything from other files to T.json file?
Thanks :)
Try
1. Add following methods getJsonFromAssetFile and writeFile to your code
2. Read json file
String content = getJsonFromAssetFile("T_Difficult.json");
3 Create final json (as mentioned)
JSONObject finalJson = new JSONObject();
try {
JSONObject jsonObject = new JSONObject(content);
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonObject);
finalJson.put("T", jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
4. Write final json to file
writeFile(finalJson.toString().getBytes());
writeFile
public static void writeFile(byte[] data, File file) throws IOException {
BufferedOutputStream bos = null;
try {
FileOutputStream fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(data);
}
finally {
if (bos != null) {
try {
bos.flush ();
bos.close ();
}
catch (Exception e) {
}
}
}
}
getJsonFromAssetFile
public static String getJsonFromAssetFile(Context context, String jsonFileName) {
String json = null;
try {
InputStream is = context.getAssets().open(jsonFileName);
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;
}
NOTE: Read json asset file using getJsonFromAssetFile method and Write file on internal/external storage and provide proper path to writeFile method

Gson Library Write in the file and only change a specific value

I'm currently using the Gson library to write/read a .json file. I have this method to write intro the json.
public static void write(String key, String value){
GeneralJsonConfig gjc = new GeneralJsonConfig();
if(key.equals("testKey")){
gjc.setaucString(value);
}
Gson gson = new Gson();
String json = gson.toJson(gjc);
try{
FileWriter fw = new FileWriter(launcherConfigFile);
fw.write(json);
fw.close();
} catch(IOException e) {
}
}
But lets say i have this .json:
{"testKey": "some test", "testKey2": "test 3"}
and i only want to change the thestKey from "some test" to another text and the other key/values will remain as they are now, but with my method the other values/key just dissaper, how can i solve this to make the other key/values stay ?
Update:
Found an answer based on sam100rav answer, i simply read the complete json file to get the vaules and then write them again with the changed that i want done:
public static void write(String key, String value){
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try{
BufferedReader br = new BufferedReader(new FileReader(launcherConfigFile));
GeneralJsonConfig gjcObject = gson.fromJson(br, GeneralJsonConfig.class);
if(key.equals("testKey")){
gjc.setaucString(value);
}
String json = gson.toJson(gjcObject);
FileWriter fw = new FileWriter(launcherConfigFile);
fw.write(json);
fw.close();
br.close();
} catch (IOException e){
main.er.LogError("23", "");
}
JSONObject obj = new JSONObject();
obj.put("testKey", "some test");
obj.put("testKey2", "test 3");
if(key.equals("testKey")){
obj.put("testKey", value);
}
String json = obj.toString();
try{
FileWriter fw = new FileWriter(launcherConfigFile);
fw.write(json);
fw.close();
}
Found an answer based on sam100rav answer, i simply read the complete json file to get the vaules and then write them again with the changed that i want done:
public static void write(String key, String value){
Gson gson = new GsonBuilder().setPrettyPrinting().create();
try{
BufferedReader br = new BufferedReader(new FileReader(launcherConfigFile));
GeneralJsonConfig gjcObject = gson.fromJson(br, GeneralJsonConfig.class);
if(key.equals("testKey")){
gjc.setaucString(value);
}
String json = gson.toJson(gjcObject);
FileWriter fw = new FileWriter(launcherConfigFile);
fw.write(json);
fw.close();
br.close();
} catch (IOException e){
main.er.LogError("23", "");
}

How to save data with gson in a json file?

In my web application I succeed in displaying data in html table using mybatis. Now I want to save the records of the Mysql table in a json file and create an array of users, I used Gson, the problem is that just one record saved in the file. Thanks.
Here the result in file.json:
{"data":
[
{"id":2,"Name":"Mike"}
]
}
servlet.java
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
for (User u : users) {
Gson gson = new Gson();
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
session.close();
You write all the users in same file C:\\file.json so just the last iteration of the loop saved.
You can convert the object List<User> into json and write it once (no needed loop)
Example:
try (Writer writer = new FileWriter("Output.json")) {
Gson gson = new GsonBuilder().create();
gson.toJson(users, writer);
}
I was previously using outputStream.writeObject and Serializable with default writer/reader for saving object data. Because of problems with code sustainability I have been after something else. This is the result. That BufferedWriter is mandatory, otherwise write speed drops 8 times. Notice that UTF-8 declaration which is default encoding of Json. Not sure whether not declaring it is safe.
Example:
private void saveJson(Object object, Type type, String directory, String fileName) {
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
OutputStream outputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
outputStream = new FileOutputStream(file);
BufferedWriter bufferedWriter;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream,
StandardCharsets.UTF_8));
} else {
bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
}
gson.toJson(object, type, bufferedWriter);
bufferedWriter.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(saveJson, "saveUserData, IOException e: '" + e + "'");
} finally {
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(saveJson, "saveUserData, finally, e: '" + e + "'");
}
}
}
}
private Object loadJson(Type type, String directory, String fileName) {
Object jsonData = null;
File file = new File(getApplicationContext().getDir(directory, Context.MODE_PRIVATE),
fileName);
InputStream inputStream = null;
Gson gson = new GsonBuilder().enableComplexMapKeySerialization().setPrettyPrinting()
.create();
try {
inputStream = new FileInputStream(file);
InputStreamReader streamReader;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
streamReader = new InputStreamReader(inputStream,
StandardCharsets.UTF_8);
} else {
streamReader = new InputStreamReader(inputStream, "UTF-8");
}
jsonData = gson.fromJson(streamReader, type);
streamReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, FileNotFoundException e: '" + e + "'");
} catch (IOException e) {
e.printStackTrace();
if (DEBUG) Log.e(TAG, "loadJson, IOException e: '" + e + "'");
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
if (DEBUG) Log.e(TAG, "loadJson, finally, e: '" + e + "'");
}
}
}
return jsonData;
}
where Type for example:
Type type = new TypeToken<Map<String, Object>>() { }.getType();
Quick fix to your code:
SqlSession session = MyBatisSqlSessionFactory.getSession();
List<User> users = session.selectList("dao.UserDao.findAll");
try {
JsonWriter writer = new JsonWriter(new FileWriter("C:\\file.json"));
writer.beginObject();
writer.name("data");
writer.beginArray();
for (User u : users) {
writer.beginObject();
writer.name("id").value(t.getId());
writer.name("name").value(t.getNom());
writer.endObject();
}
writer.endArray();
writer.endObject();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
However, in the case that your User class looks like this:
public class User {
String id;
String name;
}
Then you don't need to code the adapter as Gson is able to automatically generate the JSON code for a class that only has primitives (ints, Strings, etc.). So your code would look as #roy-shmuli but only if you omit the data and keep only the array as List can be completely generated without an adapter. The JSON code generated would look like this:
[
{"id":1, "name": "Mike"},
{"id":2, "name": "Lucy"}
]
Hope it helps to the beginners.

What am I doing wrong in this parsing?

I am currently parsing through reddit.com/.json with Google Gson and having some trouble. After doing some research I found a way to parse through json with Gson without making a lot of classes. I am using this method. Here is my code so far:
import java.io.*;
import java.net.*;
import com.google.gson.*;
public class Subreddits {
public static void main(String[] args) {
URL u = null;
try {
u = new URL("http://www.reddit.com/.json");
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection yc = null;
try {
yc = u.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
String json = null;
StringBuilder sb = new StringBuilder();
try {
while ((json = in.readLine()) != null){
sb.append(json);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
json = sb.toString();//String of json
System.out.println(json);
//I want to get [data][children][data][subreddit]
JsonParser parser = new JsonParser();
JsonObject rootObj = parser.parse(json).getAsJsonObject();
JsonObject locObj = rootObj.getAsJsonObject("data").getAsJsonObject("children").getAsJsonObject("data");
String subreddit = locObj.get("subreddit").getAsString();
System.out.println(subreddit);
}
}
You are trying to get the element "children" as a JsonObject, but it is a JsonArray because it is surrounded by [ ]...
Try something like this:
JsonParser parser = new JsonParser();
JsonObject rootObj = parser.parse(json).getAsJsonObject();
//Here is the change
JsonObject locObj = rootObj
.getAsJsonObject("data")
.getAsJsonArray("children")
.get(0)
.getAsJsonObject()
.getAsJsonObject("data");
String subreddit = locObj.get("subreddit").getAsString();
Note: I assume that you only want to get the data of the first element of the "children" array, since it seems that it is what you want looking at your code and mainly looking at this other question of yours.
The children object returns an Array that you must iterate.
public static void main(String[] args) {
URL u = null;
try {
u = new URL("http://www.reddit.com/.json");
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection yc = null;
try {
yc = u.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
String json = null;
StringBuilder sb = new StringBuilder();
try {
while ((json = in.readLine()) != null) {
sb.append(json);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
json = sb.toString();// String of json
System.out.println(json);
// I want to get [data][children][data][subreddit]
JsonParser parser = new JsonParser();
JsonObject rootObj = parser.parse(json).getAsJsonObject();
JsonArray locObj = rootObj.getAsJsonObject("data").getAsJsonArray("children");
/* Iterating children object */
Iterator<JsonElement> iterator = locObj.iterator();
while(iterator.hasNext()){
JsonElement element = iterator.next();
JsonElement subreddit = element.getAsJsonObject().getAsJsonObject("data").get("subreddit");
System.out.println(subreddit.getAsString());
}
}
You don't need to create try..catch block for every expression that can throw an exception.
JsonParser.parse() method accepts Reader (e.g. InpustStreamReader) instance so you don't have to read JSON on your own.
root[data][children] is an array of objects so you'll have to iterate over them in order to gain access to individual objects.
I believe you want to read all [subredit]s into some sort of collection, Set I pressume?
public static void main(String[] args) {
try {
Set<String> subreddits = new HashSet<>();
URL url = new URL("http://www.reddit.com/.json");
JsonParser parser = new JsonParser();
JsonObject root = parser.parse(new InputStreamReader(url.openConnection().getInputStream())).getAsJsonObject();
JsonArray children = root.getAsJsonObject("data").getAsJsonArray("children");
for (int i = 0; i < children.size(); i++) {
String subreddit = children.get(i).getAsJsonObject().getAsJsonObject("data").get("subreddit").getAsString();
subreddits.add(subreddit);
}
System.out.println(subreddits);
} catch (IOException e) {
e.printStackTrace();
}
}
This code returns:
[IAmA, worldnews, technology, news, todayilearned, gaming, AskReddit, movies, videos, funny, bestof, science, WTF, politics, aww, pics, atheism, Music, AdviceAnimals]

Categories