Unexpected token END OF FILE at position 0 while parsing JSON - java

In order to find out weather the JSON element is JSONArray or JSONObject type, I am getting Unexpected token END OF FILE at position 0 error.
My JSON is:
{"colors":[{"color":"red","value":"#00"},{"color":"white","value":"#000g"}]}
My code is:
java.io.FileReader reader = new java.io.FileReader("jsonpath");
org.json.simple.parser.JSONParser parser = new JSONParser();
System.Out.Println("aaaaaa JSON Class: "+parser.parse(reader).getClass());
if(parser.parse(reader) instanceof org.json.simple.JSONArray)
System.Out.Println("JSONArray");
else if(parser.parse(reader) instanceof org.json.simple.JSONObject)
System.Out.Println("JSONObject");
When I run above code it shows this output
aaaaaa JSON Class: class org.json.simple.JSONObject Unexpected token END OF FILE at popsition 0
at org.json.simple.parser.JSONParser(Unknown Source)
.
.
.
<rest of the exception>
I don't understand why this exception is occurring.
Please help me out.
Some more details after edit:
My this code is working fine with the given json file:
java.io.FileReader reader = new java.io.FileReader("jsonpath");
org.json.simple.parser.JSONParser parser = new JSONParser();
org.json.simple.JSONObject object = (JSONObject)parser.parse(reader);
System.Out.Println("JSONObject: "+object);
org.json.simple.JSONArray array = (JSONArray)object.get("colors");
System.Out.Println("JSONArray: "+array);
Output of above code:
JSONObject: {"colors":[{"color":"red","value":"#00"},{"color":"white","value":"#000g"}]}
JSONArray: [{"color":"red","value":"#00"},{"color":"white","value":"#000g"}]
But I want to dynamically parse the JSON without knowing the JSON structure.
I want to do something like this:
if(json is object)
JSONObject object = (JSONObject)parser.parse(reader);
else if (json is array)
JSONArray array = (JSONArray)parser.parse(reader);
Thanks.

You're repeatedly parsing the same Reader. The first call exhausts it and then each subsequent call sees an empty stream.

Parse the reader only once. Here is the working code:
java.io.FileReader reader = new java.io.FileReader("jsonpath");
org.json.simple.parser.JSONParser parser = new JSONParser();
Object p = parser.parse(reader);
if(p instanceof org.json.simple.JSONArray){
System.Out.Println("JSONArray");
org.json.simple.JSONArray object = (JSONArray)p;
}
else if(p instanceof org.json.simple.JSONObject){
System.Out.Println("JSONObject");
org.json.simple.JSONObject object = (JSONObject)p;
}
Output of above code
JSONObject

Well, error may occur when you try to pass wrong path.
So check your path to json file properly. Try to use absolute path at first.
Here is my procedure:
private static void ReadWithEncoding(String filePath, String encoding) {
StringBuilder json = new StringBuilder();
File f = new File(filePath);
if (f.exists() && f.isFile()) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), encoding));
String line;
while ((line = br.readLine()) != null) {
json.append(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(json);
}
}
You may run it like this for UTF8:
ReadWithEncoding("D:/file.json", "UTF8");
For Cyrillic symbols:
ReadWithEncoding("D:/file.json", "Cp1251");

I too was getting this error ("Unexpected token END OF FILE at position 0.").
I was using same instance of com.google.gson.Gson and org.json.simple.parser.JSONParser on multiple threads.
Now I changed the code and created new instance of these on each thread, and that solved the issue.
gson = new GsonBuilder().create();
parser = new JSONParser();

Related

When streaming a Json file with GSON's JsonReader, can you dump an object to string?

I am working in Java using the GSON library to process a huge JSON document.
I absolutely cannot load this into memory, it is upwards of 8G and will crash the JVM with an OOM if I try to.
So I use JsonReader to process the stream of JSON.
There are certain times when I reach a BEGIN_OBJECT that want to just dump the contents of the object to string instead of processing each individual element.
For example, I am parsing something like this:
[ { "SchemaVersion":"15.0.0.0","LibraryVersion":"16.0.7324.1200","ErrorInfo":{ "ErrorMessage":"Access denied. You do not have permission to perform this action or access this resource.","ErrorValue":null,"TraceCorrelationId":"03ab459e-7076-5000-c1a7-196f1fc54384","ErrorCode":-2147024891,"ErrorTypeName":"System.UnauthorizedAccessException" },"TraceCorrelationId":"03ab459e-7076-5000-c1a7-196f1fc54384" } ]
When I get to ErrorInfo, I just want that as a string instead of parsed out. I don't want to have to parse each piece.
So here is the code:
try (InputStream is = (InputStream)response.getEntity();
InputStreamReader inputStreamReader = new InputStreamReader(is);
JsonReader jsonReader = new JsonReader(inputStreamReader)) {
if (jsonReader.peek() != JsonToken.BEGIN_ARRAY) {
return;
}
jsonReader.beginArray();
while (jsonReader.hasNext()) {
jsonReader.beginObject(); // Start of the default object on every request
jsonReader.skipValue(); // name SchemaVersion
jsonReader.skipValue(); // value
jsonReader.skipValue(); // name LibraryVersion
jsonReader.skipValue(); // value
jsonReader.skipValue(); // name ErrorInfo
if (jsonReader.peek() == JsonToken.BEGIN_OBJECT) {
// I want to dump the upcoming object to string here
...
Is it possible to dump the contents of the json reader for a given begin object until it ends to string?
Similar question, but not quite the same: Get a dump of a section (object) of JSON
Special thanks to https://stackoverflow.com/users/3389828/nikhil for the answer in the comments. You can use Gson.fromJson(jsonReader, Map.class) for this exact situation.
Gson gson = new Gson();
try (InputStream is = (InputStream)response.getEntity();
InputStreamReader inputStreamReader = new InputStreamReader(is);
JsonReader jsonReader = new JsonReader(inputStreamReader)) {
if (jsonReader.peek() != JsonToken.BEGIN_ARRAY) {
return;
}
jsonReader.beginArray();
while (jsonReader.hasNext()) {
Map header = gson.fromJson(jsonReader, Map.class);
if (header.get("ErrorInfo") != null) {
String errorDump = ((Map)header.get("ErrorInfo")).toString();
// Now I have the error dump I need but I also
// didn't load the entire thing into memory!
...
more info: https://javadeveloperzone.com/java-8/java-parse-large-json-file-gson-example/

Appending jsonobject to an existing jsonobject

I'm having a problem with Json file reading and writing. I want to append something into a json file but it doesn't work properly: it just put in a new jsonobject without the ',' to divide it from the previous one. I searched everywhere, on every site, but nothing that gave me an input on how to do it properly.
For example, I have a json file like this:
{
"Example":{
"Ok":"Ok1",
"Nice":"Nice1",
"Hi":"Hi1",
"Hello":"Hello1",
"Right":"Right1",
"Wow":"Wow1"
}
}
And I want to make it appear like this:
{
"Example":{
"Ok":"Ok1",
"Nice":"Nice1",
"Hi":"Hi1",
"Hello":"Hello1",
"Right":"Right1",
"Wow":"Wow1"
},
"Example1":{
"Ok":"Ok2",
"Nice":"Nice2",
"Hi":"Hi2",
"Hello":"Hello2",
"Right":"Right2",
"Wow":"Wow2"
}
}
So, I tried using this code:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonObject jsonObject = new JsonObject();
JsonObject dati = new JsonObject();
dati.addProperty("Cognome", StringUtils.capitalize((fields[0].getText())));
dati.addProperty("Nome", StringUtils.capitalize((fields[1].getText())));
dati.addProperty("Sesso", lblSesso.getText());
dati.addProperty("Luogo di nascita", StringUtils.capitalize((fields[2].getText())));
dati.addProperty("Provincia", lblProvincia.getText());
dati.addProperty("Data di nascita", fieldDDN.getText());
jsonObject.add(codfis, dati);
String json = gson.toJson(jsonObject);
try (BufferedReader br = new BufferedReader(new FileReader("CodFisCalcolati.json"));
BufferedWriter bw = new BufferedWriter(new FileWriter("CodFisCalcolati.json", true))) {
String jsonString = gson.fromJson(br, JsonElement.class).toString();
JsonElement jelement = new JsonParser().parse(jsonString);
JsonObject jobject = jelement.getAsJsonObject();
jobject.add(codfis, dati);
String resultingJson = gson.toJson(jelement);
bw.write(resultingJson);
bw.close();
} catch (IOException e1) { e1.printStackTrace(); }
But when I use it, it give me this output :
{
"Example":{
"Ok":"Ok1",
"Nice":"Nice1",
"Hi":"Hi1",
"Hello":"Hello1",
"Right":"Right1",
"Wow":"Wow1"
}
}{
"Example":{
"Ok":"Ok1",
"Nice":"Nice1",
"Hi":"Hi1",
"Hello":"Hello1",
"Right":"Right1",
"Wow":"Wow1"
},
"Example1":{
"Ok":"Ok2",
"Nice":"Nice2",
"Hi":"Hi2",
"Hello":"Hello2",
"Right":"Right2",
"Wow":"Wow2"
}
}
That's output, you see, it'wrong and i don't know how to make the code to give me a different output.
I'm using Gson 2.8.5 and I would rather not change to another library.
You change the question but now the answer to your new question is you use the same file to read and write. That's why you add the data inside ot the file. Change the name of the file that you write and see if you have problems
Please check if "br" is not null.
According to the specification of the method fromJson it returns:
an object of type T from the string. Returns null if json is null.
If this is the case than you call on the null toString() method and you get null pointer exception

Converting JSON to XML gives invalid XML

I am trying to convert a valid JSON file to XML.
InputStream is = new FileInputStream(file);
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
String line = buf.readLine(); StringBuilder sb = new StringBuilder();
while(line != null){
sb.append(line);
line = buf.readLine();
}
//form the string
String jsonStr = sb.toString();
//save to xml
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject) parser.parse(jsonStr);
String xml = XML.toString(json);
Here is my dependencies:
import org.json.XML;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
The input JSON is like this:
{"created":"2016-12-22T10:46:40.584Z","createdBy":"ish"}
The output XML looks like:
"{"createdBy":"ish","created":"2016-12-22T10:46:40.584Z"}"
Your problem is that you mix two APIs : json-simple and org.json.
Here :
String xml = XML.toString(json);
You pass a org.json.simple.JSONObject object to the org.json.XML.toString(Object) method.
What you want to pass is a org.json.JSONObject.
Actually, you don't need to use json-simple as you can create a JSONObject with org.json and more particularly a org.json.JSONObject. Which finally is a very good thing as XML.toString() would produce the expected result with an instance of that.
So change your code such as :
JSONObject json = new JSONObject(jsonStr);
String xml = XML.toString(json);
Optionally you can add the tag name of the enclosing element :
String xml = XML.toString(json, "foo");
Note that XML.toString(Object) is not necessary a very good designed API.
It accepts an Object as parameter and so relies on instanceof to apply the suitable processing.
The mapping to XML is done only if the parameter type belongs to some specific types : org.json.JSONObject, org.json.JSONArray, Java array.
And if it is not the case, a single thing is do : special characters are escaped such as ". As a org.json.simple.JSONObject doesn't make part of the expected type, the " of the JSONObject parameter were kept and the escaping converted them to ". Whereas the weird result you get :
"{"createdBy":"ish","created":"2016-12-22T10:46:40.584Z"}"

Read Multiple JSON object from a Text File

My Question is similar to what has been asked here .
few points :
I can not change the format. (No commas to be added etc)
This is basically a huge .txt file containing 1000's of Json objects.
My Json objects are HUGE.
This is what I am doing right now :
FileReader fileReader = new FileReader(fileName);
BufferedReader reader = new BufferedReader(fileReader);
String data = "";
while((data = reader.readLine()) != null){
ObjectMapper mapper = new ObjectMapper();
Map<String,String> map = mapper.readValue(data, Map.class);
}
Currently I am using Jackson and Ideally I would like to read one Json Object from the file at a time, Parse it and then move on to the next one. I need to count let say unique number of id's from these Json object and do more operations. It will be best to read them one by one.
Is jackson would be the best way going forward ?
This is a good example of parsing huge Json, But it deals with only one object per file. My file has huge Jsons (1000s of them).
Here is a Jackson example that works for me. I have thousands json objects (tokens) in a single json file. This code will iterate through the file read each token and print it's serial.
Required imports:
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
Using Jackson to read multiple json objects from FileInputStream:
try (FileInputStream fis = new FileInputStream("D:/temp/tokens.json")) {
JsonFactory jf = new JsonFactory();
JsonParser jp = jf.createParser(fis);
jp.setCodec(new ObjectMapper());
jp.nextToken();
while (jp.hasCurrentToken()) {
Token token = jp.readValueAs(Token.class);
jp.nextToken();
System.out.println("Token serial "+token.getSerialNumber());
}
}
Here is a more JAVA 8ish solution for your query, I always lean toward BufferedReader over InputStreams for any place where parsing is going to be done a lot of time.
ObjectMapper mapper = new ObjectMapper();
JsonFactory jsonFactory = new JsonFactory();
try(BufferedReader br = new BufferedReader(new FileReader("luser.txt"))) {
Iterator<luser> value = mapper.readValues( jsonFactory.createParser(br), luser.class);
value.forEachRemaining((u)->{System.out.println(u);});
}
The deserialization for each object happens as part of next(), in each iteration.
Here is how I used Gson's JSONReader API to handle similar requirement as above
public static List<YOURPOJO> readTraceLog(String filepath) throws IOException {
Gson gson = new Gson();
JsonReader jsonReader = new JsonReader(new FileReader(filepath));
// important as handles unwanted formatting stuffs such empty spaces
jsonReader.setLenient(true);
boolean start = true; // start of read
jsonReader.beginObject(); // first object begins
//List to hold object
List<YOURPOJO> completeList = new ArrayList<YOURPOJO>();
//YOURPOJO has two attributes one is ID and other is list of ANOTHERPOJO
while (jsonReader.hasNext()) {
if (!start) {
//to stop end of Document
if (jsonReader.peek().toString().matches("END_DOCUMENT")) {
break;
}
//continue reading object as the come -{
jsonReader.beginObject();
}
start = false;
YOURPOJO pojo = new YOURPOJO();
//read attribute id
String name = jsonReader.nextName();
pojo.setId(name);
//list to store ANOTHERPOJO objects
List<ANOTHERPOJO> tempList = new ArrayList<ANOTHERPOJO>();
//begin reading list - [
jsonReader.beginArray();
while (jsonReader.hasNext()) {
ANOTHERPOJO t = gson.fromJson(jsonReader, ANOTHERPOJO.class);
tempList.add(t);
}
//end reading list - ]
jsonReader.endArray();
//store data
pojo.setTraceDetails(tempList);
completeList.add(YOURPOJO);
//end of object - }
jsonReader.endObject();
}
jsonReader.close();
return completeList;
}

Format of the following response?

I'm using Bing's auto suggest feature to auto suggest me terms given a query. You can find the tool here: http://api.bing.com/osjson.aspx?query=pe as you can see it's returning a strange format that isn't quite JSON. Is this a specific standard different to JSON? I've attempted parsing it as JSON using...
InputStream i = new URL(url).openStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(i, Charset.forName("UTF-8")));
JSONObject json = new JSONObject(readAll(reader));
but I get the error A JSONObject text must begin with '{' found:" at 2 [character 3 line 1]
readAll =
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
Your example is valid JSON:
["pe",["people","people search","petsmart","petco","petfinder","pep boys","people finder","people of walmart"]]
It is not object, it is array, which contains string at the first position and another array at the second. So try parse as JSONArray, not as JSONObject.
A JSON Object starts with a { and ends with a }, which a JSONObject class was designed to parse.
A JSON Array starts with a [ and ends with a ], which a JSONArray class was designed to parse.
I hope this helps.

Categories