Parsing a java.io.File into JSON using GSON - java

I'm sending a file over the network which is in JSON format and wanting to retrieve information from it. The file is created using the File.createTempFile method. Here's the code:
File patchFile = File.createTempFile("indexer", ".pf", null);
try(FileOutputStream fos = new FileOutputStream(patchFile)) {
byte[] patchFileBytes = new byte[payloadLength];
buffer.readBytes(patchFileBytes);
fos.write(patchFileBytes);
}
I'm trying to find the best way to read the patchFile as JSON and get values from it. The generated files structure looks like this(on the client):
{
"0": [
{
"fileId": "Cache.dat",
"fileChecksum": "d41d8cd98f00b204e9800998ecf8427e"
},
{
"fileId": "Character.fbx",
"fileChecksum": "d41d8cd98f00b204e9800998ecf8427e"
},
{
"fileId": "Skybox.png",
"fileChecksum": "d41d8cd98f00b204e9800998ecf8427e"
}
],
"1": [
{
"fileId": "indexer.pf",
"fileChecksum": "f8130e38ce5c58ccbf200d24c2629632"
}
]
}
Currently I've got the file being sent over and read into memory as you can see above, but I'm unsure as to where to go from here on actually reading the data, could anyone help me out?
I'm using GSON.

What I would suggest is to avoid writing to a temporary file, instead wrap the buffer with a reader and use in one of the API's
(I'm assuming that the buffer is an InputStream, then use java.io.InputStreamReader to convert it into a Reader)
GSON has a lot of API's to perform your required task:
Examples:
To follow the iterative approach, then look at com.google.gson.JsonParser#parse it accepts reader or string to get elements.
If you know what is the type of the element being deserialized, then you can look at using com.google.gson.Gson#fromJson methods.
See the following API docs, it might be helpful:
JsonStreamParser
JsonParser
Gson

You did not mention how big your file can be. If it is not too big then you could just use Apache Commons IO and IOUtils.toString and read the entire file content into String. And since you already know GSON it should be pretty simple from there.

Related

How to parse json file in Weka using JSONLoader in Java IDE?

I want to use Weka in order to parse an existing json file in java eclipse. I believe this can be done using the JSONLoader class. I am working on Naive Bayes classifier.
This is the data that I want to parse.
{"header":{
"relation":"relationtest",
"attributes":{
"name":"Nominal",
"company":"Nominal",
"city":"Nominal",
"country":"Nominal"
}
},
"data":[
["Andrew","AS16509 Amazon.com, Inc.","Washington","UnitedStates"],
["Kyle","AS16509 Amazon.in, Inc.","NewDelhi","India"]
]
}
But, I end up getting a 'java.lang.NullPointerException' when I run the below code snippet
FileInputStream fis = new FileInputStream(argv[0]);
JSONLoader loader = new JSONLoader();
loader.setSource(fis);
Instances data = loader.getDataSet();
Note: The json file is passed as an argument.
I believe there is some problem with the way the attributes are written.
How can I solve this issue?

Best way to send a JSon object from Servlet

The question can seem simple, but I didn't find a good answer yet. I need to send a JSon structure (build with an unspecified libretry I'm currently developing) from a Servlet to a remote page.
I'm interested in the best way to send the structure.
I mean, in my Servlet, inside the doPost() event, how should I manage the send?
I was thinking about 2 scenarios:
try (PrintWriter out = response.getWriter()) {
out.print(myJSon.toString(); // <- recursive function that overrides
// toString() and returns the entire JSon
// structure
} (...)
or
try (OutputStream os = response.getOutputStream()) {
myJSon.write(os, StandardCharsets.UTF8); // <- function that
// recursively writes chunk of my JSon structure
// in a BufferWriter created inside the root write function
// forcing UTF-8 encoding
} (...)
Or something different, if there's a better approch.
Note that the JSon structure contains an array of objects with long text fields (descriptions with more than 1000 characterd), so it can be quite memory consuming.
For why I'm not using standard JSon libreries, it's because I don't know them and I don't know if I can trust them yet. And also I don't know if I will be able to install them on the production server.
Thanks for your answers.
From your question i see multiple points to adress:
How to send your JSon
What JSon library can you use
How to use the library in production
How to send your JSon
From your code this seems to be an HTTP response rather than a POST on your Servlet so you need to know how to send a JSON string as an HTTP response's body
Do you use a framework for your web server or are you handling everything manually ? If you use a framework it usually does it for you, just pass the JSON String
If your doing it manually:
try (PrintWriter pw = response.getWriter()) {
pw.write(myJson.toString());
}
or
try (OutputStream os = response.getOutputStream()) {
os.write(myJson.toString().getBytes());
}
Both are valid, see Writer or OutputStream?
Your JSON's size shouldn't matter given what your saying, it's just text so it won't be big enough to matter.
What libraries can you use
There are a lot of JSON libraries for Java, mainly:
Jackson
GSon
json-io
Genson
Go for the one you prefer, there will be extensive documentation and resources all over google
How to use in production
If you are not sure you are able to install dependencies on the production server, you can always create an uber-jar (See #Premraj' answer)
Basically, you bundle the dependency in your Jar
Using Gson is good way to send json
Gson gson = new Gson();
String jsonData = gson.toJson(student);
PrintWriter out = response.getWriter();
try {
out.println(jsonData);
} finally {
out.close();
}
for detail json response from servlet in java

Is there a better/easier way to update a json file in Java?

Say, I have a json file like below:
[{
"obj1_key1":"aa",
"obj1_array":[{"e1":"11"},{"e2":"22"}]
},
{
"obj2_key1":"cc",
"obj2_key2":"dd"
}]
Now I want update the file into something like below:
[{
"obj1_key1":"aa",
"obj1_array":[{"e1":"11"},{"e2":"22"},{"e3":"333"}]
},
{
"obj2_key1":"cc",
"obj2_key2":"dd"
}]
I tried using ObjectMapper to parse the file like
JsonNode jsonFile = new ObjectMapper().readTree(new File("file.json");
however then I need to find the obj1_array and append a json object, then write the json object back to the file. And I don't think the way I load the json file as a JsonNode is a easy way because I should convert it between Json/JsonArray back and forth. So I'm wondering is there a simpler way to make this work? Really appreciate that.
if it is just a one-off case, you can use your preferred mechanism, but if it is going to used often, I would prefer
Convert the JSON to a POJO ( using some parser eg Jackson )
Update the requisite fields
Return the Json object.

How to append object to a json file with JSR 353 (Java API for JSON Processing)

Using JSR-353 (https://jsonp.java.net/index.html)
I would like to open a json file and append some object in the root array, eg :
[{"foo":"bar"}]
I would like with a code about like this :
try(JsonGenerator writer = Json.createGenerator(new FileOutputStream(this.file))){
writer.writeStartObject().write("hello", "world").writeEnd();
} catch (IOException e) {
e.printStackTrace();
}
And obtain in the end :
[
{"foo":"bar"},
{"hello":"world"}
]
Note : I don't want to have to load the full json in-memory to append my data.
Note : I don't want to have to load the full json in-memory to append
my data.
Basically, you can't. You would have to parse the full data structure, so that your write(..) would know where to write. Otherwise, it's just appending somewhere and that might break the JSON format.
So read the JSON from the file, generate a JsonArray from it. Create a new JsonObject from your values. Add it to the array. Then write the full array.
You can't simply "append". In the general case you must read in the JSON, modify the tree-structured memory image, then "serialize" it back to linear JSON.
In very simple cases such as the above you could in theory seek to the end, backspace over the closing ], then write out ,, the second object, and a new closing ], but it's not a general solution to updating JSON.

stream a single value as JSON in a whole JSON map

I have a JSON of following format
{ "a":"b" , "Content" : <Content of file FILEA> , "x" : y" }
and so on.
FILEA is too big that i cant open and load it to main memory.
Is there any option where i can stream this json to a webservice without using much of main memory using Java.
For example , it would be awesome if there is something like
writer = new JsonWriter(new FileWriter("user.json"));
writer.beginObject(); // {
writer.name("name");
writer.value("messagesPart1"); // "messages" :
writer.flush();
writer.value("messagesPart2"); // "messages" :
writer.flush();
writer.value("messagesPart3"); // "messages" :
writer.endObject();
}
And the content of user.json fie is
{ "name" : "messagesPart1messagesPart2messagesPart3"}
I recommend you to use the Jackson library (one of the most powerful for Json in Java).
It has the functionality to stream Json to OutpuStream (so you could have a web socket or an open connection to output the content...). Here is the high level doc: Generator.
There is also a use case (Twittter) that makes use of this generator, check this post
But the Jakson quick start has also a good introduction
This blog link have some usefull info on the same - http://architectvm.blogspot.in/2012/02/stream-single-value-as-json-in-whole.html

Categories