java duplicate key in same json object - java

I am trying to parse a JSON response using jsonObject library in Java, but receiving exception with duplicated key. I need to parse this JSON as it is, without any loop and without any conversion. Some solution stated that I have to convert those values to array, so I need your suggestion. Is there any library that can parse my json which has duplicated key without any change?
This is my code :
BufferedReader in = new BufferedReader(
new InputStreamReader(c.getInputStream())); //stream to resource
String inputLine;
StringBuffer res = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
res.append(inputLine);
}
JSONObject json = new JSONObject(res.toString());
my error response :
Exception in thread "main" org.json.JSONException: Duplicate key "Account"
at org.json.JSONObject.putOnce(JSONObject.java:1121)
at org.json.JSONObject.<init>(JSONObject.java:208)
at org.json.JSONTokener.nextValue(JSONTokener.java:362)
at org.json.JSONObject.<init>(JSONObject.java:208)
at org.json.JSONTokener.nextValue(JSONTokener.java:362)

you can make use of net.sf.json.JSONObject. It will accept JSON with the duplicate key.
This library will retain the duplicated values by storing them into arrays. If multiple same keys are available it will create one key with all the values as Array.
And also the coding part is just a single line. Once you parsed the json using net.sf.json.JSONObject then you can supply this to jackson library.
JSONObject jsonObject = JSONObject.fromObject( "{ \"a\": \"a\", \"a\": { \"b\": {},\"b\": true}}" );
System.out.println( "net.sf.json.JSONObject: " + jsonObject );
JsonNode jsonNode = new ObjectMapper().readTree( jsonObject.toString() );
System.out.println( "com.fasterxml.jackson.databind.JsonNode" + jsonNode );
Output:
net.sf.json.JSONObject: {"a":["a",{"b":[{},true]}]}
com.fasterxml.jackson.databind.JsonNode{"a":["a",{"b":[{},true]}]}
Maven dependency of net.sf.json
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>

Related

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"}"

Unable to display response from the webservices call in codename one

I am getting this JSON response from my webservices
{root:[{name:abc, surname:xyz}]} and I'm trying to display only the Key:Value from the response using label.
I am using the add component method
hi.addComponent(new Label(""+ response.get("/result[0]/ocassion")));
But it's showing me null value. I have followed videos on Webservices available in the codenameone website.
What should i try to get required response to be displayed on the UI.
Here is MyApplication.java code from codename one:
InputStreamReader reader = new InputStreamReader(input);
JSONParser parser = new JSONParser();
response = parser.parse(reader);
System.out.println(""+ response);
hi.addComponent(new Label(""+ response.get("/result[0]/ocassion")));
hi.getComponentForm().revalidate();
Change parse.parse to parse.parseJSON. You have to know the key to retrieve the value, you can loop through your response as follows:
InputStreamReader reader = new InputStreamReader(input);
JSONParser parser = new JSONParser();
response = parser.parseJSON(reader);
List listResponses = (List) response.get("root");
if (listResponse != null) {
for (Object listResponse : listResponses) {
Map tempHash = (Map) listResponse;
hi.addComponent(new Label("Name: " + tempHash.get("name").toString()));
hi.addComponent(new Label("Surname: " + tempHash.get("surname").toString()));
System.out.println(tempHash.get("name").toString()); //Print abc
System.out.println(tempHash.get("surname").toString()); //Print xyz
}
hi.getComponentForm().revalidate();
} else {
System.out.println("null value returned"); //Make sure you reference root and be sure it returns proper json
}

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;
}

how to read JSON from HTTP GET request?

I have created a java server which gets HTTP GET request url as
/Star/getDetails?sentMsg=data.requestorName:ABC,data.companyName:EFG,portfolios:
[{name:,placeholder:Portfolio 1,positions:[{ticker:T1234,weight:29.85},
{ticker:T2345,weight:70.15}],active:false}],analyticsDate:20140630}
I have to parse sentMsg parameter such as I am able to read each variable individually. For eg, i should be able to read data.requestorName, companyName. I am not able to find a way to do it.
request.getParameter("sentMsg") always return String.
Tried parsing it through json-simple
JSONParser jp = new JSONParser();
try {
Object obj = jp.parse(sentMsg);
JSONArray ja = (JSONArray)obj;
} catch (ParseException e) {
e.printStackTrace();
}
But this gives parse exception. I have limitation to use json-simple jar only. Any suggestion on how to do it?
Get the paramter sentMsg from HttpRequest object store it into a string. Split from comma i.e. "," and the last second token would be the json string. You can now parse it using Json simple lib and extract values from it.
Provided you have valid JSON like:
private static String jsonString = "[{name : \"stackOverFlow\"}]";
Convert it to JSONArray like:
JSONArray jsonArray = new JSONArray(jsonString );
Then you can get value out of JSONArray by looping through it:
for (int i = 0; i < jsonArray.length(); i++) { //Iterating over mediaArray
JSONObject media = jsonArray.getJSONObject(i);
String nameFromJSON = media.getString("name");
System.out.println("Name = " + nameFromJSON);
}
Output will be:
//Name = stackOverFlow

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