GSON Adding java object to json array - java

I have json {"name": "John", "tests":["apple"]}. In my Java code I want to update this json throught gson - add string field to json array and save to file to have this json - {"name": "John", "tests":["apple", "pinapple"]}. So is there a way how ? Java class for my json look like this:
public class Test{
private String name;
private List<String> tests;
// Getters/Setters
}
Reading json in java like this:
Gson gson = new Gson();
try (Reader reader = new FileReader("D:\\file.json")) {
Test js = gson.fromJson(reader, Test.class);
System.out.println(js.getName());
} catch (IOException e) {
e.printStackTrace();
}
Doing this my new json file is empty:
Gson gson = new Gson();
try (Reader reader = new FileReader("D:\\file.json")) {
Test test = gson.fromJson(reader, Test.class);
System.out.println(test.getName());
test.getTests().add("pinapple");
String newJson = gson.toJson(test);
System.out.println(newJson);
gson.toJson(test, new FileWriter("D:\\file.json"));
} catch (IOException e) {
e.printStackTrace();
}

Test test = gson.fromJson(reader, Test.class);
Once you have your Test object do:
test.getTests().add("pineapple");
Now you have the pineapple in your array. You can make your JSON string:
String newJson = gson.toJson(test);
System.out.println(newJson);
or write it back in the same file
gson.toJson(test, new FileWriter("D:\\file.json"));
EDIT: Whole code
String fileName = "D:\\file.json";
Gson gson = new Gson();
Test test = null;
try (Reader reader = new FileReader(fileName)) {
test = gson.fromJson(reader, Test.class);
} catch (IOException e) {
e.printStackTrace();
}
test.getTests().add("pineapple");
String newJson = gson.toJson(test);
System.out.println(newJson);
try (Writer writer = new FileWriter(fileName)) {
gson.toJson(test, writer);
}

Related

Jersey RESTful: How to populate DAO with a local json file?

this is my first time building a Jersey Restful web service.
The project is supposed to be a server that provides information about Reddit posts. For now, this information is stored in a large JSON file, and because it is not supposed to be manipulated, my idea is to store this information in the dao class in form of Post instances.
here is my projects' folder organisation: filesView
So my idea is to populate the dao class by reading the json file something like this:
public enum PostDao {
instance;
private Map<String, Post> posts = new HashMap<String, Post>();
private PostDao() {
//JSON parser object to parse read file
System.out.println("init");
JSONParser jsonParser = new JSONParser();
try {
FileReader reader = new FileReader("src/main/resources/data/posts.json");
//Read JSON file
Object obj = jsonParser.parse(reader);
JSONArray postsArr = (JSONArray) obj;
for (Object p : postsArr) {
JSONObject post = (JSONObject) p;
Post pobj = new Post(post.get("title"), post.get("author"));
posts.put(pobj.getId(), pobj);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
public Map<String, Post> getModel() {
return posts;
}
The problem is that I do not know where to put the json file and what the path would be.
Is there a standard folder and path to store this kind of files? Or is there a different way to populate the dao class?
I managed to find a solution which was pretty simple:
JSONParser jsonParser = new JSONParser();
try {
//get JSON file's path
InputStream in = this.getClass().getResourceAsStream("/data/posts.json");
BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8));
//Read JSON file
Object obj = jsonParser.parse(br.readLine());
for (Object p : (JSONArray) obj) {
JSONObject post = (JSONObject) p;
//add post to mapping
this.addPost(new Post(generateId(),
(String)post.get("user"),
(String)post.get("title"),
(String)post.get("date")));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
Note: my json file consisted of only one line (as text file) so that is why BufferedReader.readLine() was enough

How to fix an Out Of memory when importing a large JSON file

I want to import a JSON file with 5 GB size but it shows me an Out of memory error.
I set up the JVM by putting -Xmx7700m -Xms7700m -XX: + UseConcMarkSweepGC knowing that I have 8 GB of RAM in my computer but the program execution takes 45 minutes and then shows me this error:
i'm using maven depedency "com.googlecode.json-simple" version : 1.1.1
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead
limit exceeded java.lang.OutOfMemoryError: Java heap space //if i put
-Xmx5000m -Xms5000m
and this is the code of importing of the JSON File
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("url.json"));
JSONObject jsonObject = (JSONObject) obj;
System.out.println(jsonObject);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
can i find another solution to divide the JSON File into parts and import it part by part?
Assuming your JSON file is a big array of JSON objects, can this assist you?:
import com.google.gson.stream.JsonReader;
import org.json.simple.JSONObject;
...
JsonReader jsonReader = new JsonReader(new InputStreamReader(new FileInputStream(theFile), StandardCharsets.UTF_8));
jsonReader.beginArray();
Gson gson = new GsonBuilder().create();
while (jsonReader.hasNext()) {
JSONObject currentJsonObject = gson.fromJson(jsonReader, JSONObject.class);
// do stuff
}
jsonReader.close();
// Create a mapper model class according with your JSON file fields. I gave an example.
public class JsonToJavaObject {
#SerializedName("Id")
#Expose
private Integer id;
#SerializedName("Name")
#Expose
private String name;
// Getter/Setter
}
// Create file from your JSON
File file = new File("url.json"); // Make sure your file name and location
// Make an input stream for the file's data
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
InputStreamReader inputStreamReader = new InputStreamReader(buf, StandardCharsets.UTF_8);
// Read stream of data
try (JsonReader jsonReader = new JsonReader(inputStreamReader)) {
Gson gson = new GsonBuilder().create();
// Create JSON object
JsonToJavaObject = gson.fromJson(jsonReader, JsonToJavaOnline.class);
} catch (Exception e) {
e.getMessage();
}

Get JSONArray and write to JSONArray

I have the following object:
{
"some_prop": "sweetvalue",
"some_list": ["0f9f822cd7e64000ac056ebc17b82f1d", "0f9f82223094fj7b82f1d"]
}
And I'm trying to get some_list and write to some_list, afterwards saving to a file. using the following code:
public String getData(String key) { // this is confusion should be getConfigValue
String data = getConfig();
JSONObject jsonData;
Object content = null;
try {
jsonData = new JSONObject(data);
if (key != null) {
content = jsonData.getString(key);
} else {
content = jsonData.toString();
}
} catch (JSONException e) {
e.printStackTrace();
}
return content.toString();
}
private void saveFile(String data) {
File file = configFile;
try (FileOutputStream fop = new FileOutputStream(file)) {
if (!file.exists()) file.createNewFile();
byte[] contentInBytes = data.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void appendToArrayValue(String uuid) {
JSONObject configData = new JSONObject(getConfig());
JSONArray mutedPlayers = configData.getJSONArray("some_list");
JSONArray uuidArray = new JSONArray(uuid);
JSONArray newArray = concatArray(mutedPlayers, uuidArray);
JSONObject newConfigData = configData.put("some_list", newArray);
saveFile(newConfigData.toString());
}
When trying to run this code, I get the following error:
org.json.JSONException: A JSONArray text must start with '[' at 1 [character 2 line 1]
I'm not sure what's really wrong, I know my code is terrible but that's it.
Looks like the error is at line JSONArray uuidArray = new JSONArray(uuid);?
Because prevoius line JSONArray mutedPlayers = configData.getJSONArray("some_list"); should work fine.
If so, you are passing not an array to new JSONArray(uuid) since uuid is your whole JSON object.

Parsing Multiple JSON Strings to Objects using json-simple

I have a socket server running, which will emit json strings for clients. I tried to use json-simple for parsing them. But, the problem I face is that, the server doesn't have any delimiter character to segregate json strings. So, my json-simple JSONParser throws ParseException.
As an alternate, I tried to use json-smart. But, in this case, the JSONParser returns only the first object and ignores rest of the string.
I'm new to this json parsing stuff. It would be great if people can direct me to correct way of handling json string streams.
Edit: - Adding JSON String and Sample Code
{"type":"response","id":"1","result":[true,0]}{"type":"response","id":"2","result":[true,1]}
Currently this method returns the single object when I use json-smart and null when json-simple is used.
public JSONObject getResponse(JSONObject request) {
String s = null;
Socket soc = null;
PrintWriter sout = null;
BufferedReader sin = null;
try {
soc = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
sout = new PrintWriter(soc.getOutputStream());
sin = new BufferedReader(
new InputStreamReader(soc.getInputStream()));
sout.println(request.toJSONString());
sout.flush();
s = sin.readLine();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
sin.close();
sout.close();
soc.close();
} catch (Exception e) {
}
}
Object response = null;
try {
response = JSONValue.parseWithException(s.toString());
}catch (ParseException e){
e.printStackTrace();
}
return (JSONObject) response;
Thanks in advance,
Kaja
I have found a solution using Jackson. Here is the code that worked for me.
MappingJsonFactory factory = new MappingJsonFactory();
JsonParser parser = factory.createParser(soc.getInputStream());
JsonToken curToken = parser.nextToken();
if (curToken != JsonToken.START_OBJECT) {
System.err.println("Not in start object!, Exiting...");
return null;
}
while (runParser.get() == true) {
if (curToken == JsonToken.START_OBJECT) {
TreeNode node = parser.readValueAsTree();
System.out.println(node.getClass().getName());
System.out.println(node);
}
curToken = parser.nextToken();
}
Thanks Kaja Mohideen! It's working with a small change in while loop.
This code works perfectly. In my case input json is in file.
libs used : jackson-core, jackson-annotation and jackson-databind
MappingJsonFactory factory = new MappingJsonFactory();
JsonParser parser = null;
File file = new File("jsontest.txt");
try {
parser = factory.createParser(file);
JsonToken curToken = parser.nextToken();
if (curToken != JsonToken.START_OBJECT) {
System.err.println("Not in start object!, Exiting...");
}
while (parser.hasCurrentToken()) {
if (curToken == JsonToken.START_OBJECT) {
TreeNode node = parser.readValueAsTree();
System.out.println(node);
}
curToken = parser.nextToken();
}
} catch (JsonParseException e) {
e.printStackTrace();
}

gson with mixed read

I'm trying to read json with gson, but I can't get a "simple" gson example to work.
From: https://sites.google.com/site/gson/streaming
public List<Message> readJsonStream(InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
List<Message> messages = new ArrayList<Message>();
reader.beginArray();
while (reader.hasNext()) {
Message message = gson.fromJson(reader, Message.class);
messages.add(message);
}
reader.endArray();
reader.close();
return messages;
}
Here's the problem, if I try with:
JsonReader reader;
Gson gson = new Gson();
gson.fromJson(reader,Program.class);
It doesn't even build.
The method fromJson(String, Class<T>) in the type Gson is not applicable for the arguments (JsonReader, Class<Program>)
There seems to be a method according to eclipse:
fromJson(JsonReader arg0, Type arg1)
Replace
import android.util.JsonReader;
with
import com.google.gson.stream.JsonReader
did it! =)
It is mentionned that the fromJson method accepts argument 0 as a String. Try to create a method that transforms the inputStream to a String.
static public String generateString(InputStream stream) {
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader buffer = new BufferedReader(reader);
StringBuilder sb = new StringBuilder();
try {
String cur;
while ((cur = buffer.readLine()) != null) {
sb.append(cur).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}

Categories

Resources