gson deserialisition of same key different values in json - java

this is my json event
{
"type":"record",
"name":"Doc",
"doc":"adoc",
"fields":[
{
"name":"id",
"type":"string"
},
{
"name":"user_friends_count",
"type":[
"int",
"null"
]
},
{
"name":"user_location",
"type":[
"string",
"null"
]
}}
am tring to deserialze it event but stuck with same "type" different values like one "type" with "string" value and other with ["string","null"] how can i iterate them?? ths is my code
import java.lang.reflect.Type;
import java.util.ArrayList;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
public class FieldaDeserialisation implements JsonDeserializer<Fields>{
public Fields deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jobj = json.getAsJsonObject();
JsonArray A1 = jobj.get("fields").getAsJsonArray();
JsonPrimitive jtype = null;
String jname = null;
for (int i = 0; i < jobj.size(); i++) {
JsonElement obj = A1.get(i);
JsonObject b1 = obj.getAsJsonObject();
jname = b1.get("name").getAsString();
if (b1.get("type").isJsonArray()) {
JsonArray jarray = b1.get("type").getAsJsonArray();
for (int j = 0; j < jarray.size(); j++) {
jtype = (JsonPrimitive) jarray.get(j);
}
}
else {
jtype = (JsonPrimitive) b1.get("type");
}
}
}
it shows me error on the same line JsonArray A1 = jobj.get("fields").getAsJsonArray(); and on line1 import java.lang.reflect.Type; the error is
Exception in thread "main" java.lang.NullPointerException
at FieldaDeserialisation.deserialize(FieldaDeserialisation.java:18)
at FieldaDeserialisation.deserialize(FieldaDeserialisation.java:1)
at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
at com.google.gson.Gson.fromJson(Gson.java:887)
at com.google.gson.Gson.fromJson(Gson.java:952)
at com.google.gson.internal.bind.TreeTypeAdapter$GsonContextImpl.deserialize(TreeTypeAdapter.java:162)
at JsonDataDeserialisation.deserialize(JsonDataDeserialisation.java:20)
at JsonDataDeserialisation.deserialize(JsonDataDeserialisation.java:1)
at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.google.gson.Gson.fromJson(Gson.java:887)
at JsonMainClass.main(JsonMainClass.java:15)
this is my main deserialisation class
import java.lang.reflect.Type;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
public class JsonDataDeserialisation implements JsonDeserializer<JsonData>{
#Override
public JsonData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
// TODO Auto-generated method stub
JsonObject jobj = json.getAsJsonObject();
String jsontype = jobj.get("type").getAsString();
String jsonname = jobj.get("name").getAsString();
String jsondoc = jobj.get("doc").getAsString();
Fields[] fields = context.deserialize(jobj.get("fields"), Fields[].class);
JsonData jdata = new JsonData();
jdata.setType(jsontype);
jdata.setName(jsonname);
jdata.setDoc(jsondoc);
jdata.setFields(fields);
return jdata;
}
}
and this is main class
import java.io.*;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
public class JsonMainClass {
public static void main(String []args)throws Exception{
String filepath = "/Users/RAGHU/Desktop/json1 .txt";
GsonBuilder gsonb = new GsonBuilder();
gsonb.registerTypeAdapter(JsonData.class, new JsonDataDeserialisation());
gsonb.registerTypeAdapter(Fields.class, new FieldaDeserialisation());
Gson gson = gsonb.create();
try(JsonReader reader = new JsonReader(new FileReader(filepath))){
reader.setLenient(true);
JsonData jdata1 = gson.fromJson(reader, JsonData.class);
System.out.println(jdata1);
}
}
}
now this an error i got with a previous way i done
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: This is not a JSON Array.
at com.google.gson.Gson.fromJson(Gson.java:899)
at com.google.gson.Gson.fromJson(Gson.java:952)
at com.google.gson.internal.bind.TreeTypeAdapter$GsonContextImpl.deserialize(TreeTypeAdapter.java:162)
at JsonDataDeserialisation.deserialize(JsonDataDeserialisation.java:20)
at JsonDataDeserialisation.deserialize(JsonDataDeserialisation.java:1)
at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.google.gson.Gson.fromJson(Gson.java:887)
at JsonMainClass.main(JsonMainClass.java:15)
Caused by: java.lang.IllegalStateException: This is not a JSON Array.
at com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:106)
at FieldaDeserialisation.deserialize(FieldaDeserialisation.java:18)
at FieldaDeserialisation.deserialize(FieldaDeserialisation.java:1)
at com.google.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:72)
at com.google.gson.Gson.fromJson(Gson.java:887)
... 7 more

Calling
Fields[] fields = context.deserialize(jobj.get("fields"), Fields[].class);
You are already receiving the Array from this, just parse the json into an Array, then iterate.
JsonArray A1 = json.getAsJsonArray();
Then you can iterate like you seems to do, using the condition on the type of type
To be cleaner, I would use a JsonElement to store the field
JsonElement type = b1.get("type");
if(type.isJsonArray()){
JsonArray array = type.getAsJsonArray();
...//ARRAY
else {
String s = type.getAsString();
...//STRING
}

Related

JAVA Error parsing JSON (stream mode) with Gson: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

UPDATE: I have adapted my code according to suggestions in the first reply but still an error is produced.
I have written the following code to parse a very large json file:
public static void main(String[] args) throws Exception {
String jsonFile="/home/zz/Work/data/wdc/WDC_ProdMatch/idclusters.json";
WDCProdMatchDatasetIndexer_2 indexer = new WDCProdMatchDatasetIndexer_2();
indexer.readClusterMetadata(jsonFile);
}
public void readClusterMetadata(String jsonFile){
try(JsonReader jsonReader = new JsonReader(
new InputStreamReader(
new FileInputStream(jsonFile), StandardCharsets.UTF_8))) {
Gson gson = new GsonBuilder().create();
jsonReader.beginObject(); //start of json array
int numberOfRecords = 0;
while (jsonReader.hasNext()){ //next json array element
Cluster c = gson.fromJson(jsonReader, Cluster.class);
long[] sizeInfo=new long[]{c.clusterSizeInOffers, c.size};
//clusterSize.put(String.valueOf(c.id), sizeInfo);
numberOfRecords++;
if (numberOfRecords%1000==0)
System.out.println(String.format("processed %d clusters", numberOfRecords));
}
jsonReader.endArray();
System.out.println("Total Records Found : "+numberOfRecords);
}
catch (Exception e) {
e.printStackTrace();
}
}
class ArrayAsStringJsonDeserializer implements JsonDeserializer<List<String>> {
#Override
public List<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String value = json.getAsString().trim();
value = value.substring(1, value.length() - 1);
return Arrays.stream(value.split(",")).map(String::trim).collect(Collectors.toList());
}
}
class Cluster {
protected long id;
protected long size;
#SerializedName("cluster_size_in_offers")
protected long clusterSizeInOffers;
#JsonAdapter(ArrayAsStringJsonDeserializer.class)
#SerializedName("id_values")
protected List<String> idValues;
#SerializedName("categoryDensity")
protected double catDensity;
#SerializedName("category")
protected String cat;
}
And the data file looks like this (first 10 lines)
{"size":4,"cluster_size_in_offers":1,"id_values":"[814914023129, w2190254, pfl60gs25ssdr, pfl60gs25ssdr]","id":2,"categoryDensity":1,"category":"Computers_and_Accessories"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[hst322440ss, g1042641]","id":3,"categoryDensity":1,"category":"Office_Products"}
{"size":4,"cluster_size_in_offers":1,"id_values":"[4051329063869, t24datr01765, t24datr01763, datr01763]","id":4,"categoryDensity":1,"category":"Automotive"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[5057195062301, sppct335a2bl]","id":7,"categoryDensity":1,"category":"Office_Products"}
{"size":3,"cluster_size_in_offers":1,"id_values":"[ 845173001269, mpnlkbusmokeam89us, lkbusmokeam89]","id":8,"categoryDensity":1,"category":"Computers_and_Accessories"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[ksw26r0100, g1104817]","id":9,"categoryDensity":1,"category":"Other_Electronics"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[5054328719897, ltr12x31r685c15]","id":11,"categoryDensity":1,"category":"Office_Products"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[model82226, sirsir822261]","id":15,"categoryDensity":1,"category":"Tools_and_Home_Improvement"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[5054328970724, sscl3816114a2bl]","id":17,"categoryDensity":1,"category":"Office_Products"}
{"size":2,"cluster_size_in_offers":1,"id_values":"[814882011647, 203932664]","id":20,"categoryDensity":1,"category":"Tools_and_Home_Improvement"}
But when the code is run on this data, an error is generated as follows:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NAME at line 1 column 3 path $.
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
at com.google.gson.Gson.fromJson(Gson.java:927)
at uk.ac.shef.inf.wop.indexing.WDCProdMatchDatasetIndexer_2.readClusterMetadata(WDCProdMatchDatasetIndexer_2.java:38)
at uk.ac.shef.inf.wop.indexing.WDCProdMatchDatasetIndexer_2.main(WDCProdMatchDatasetIndexer_2.java:25)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NAME at line 1 column 3 path $.
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
... 3 more
Any suggestions please?
In a file each line is a separate JSON Object. One problem with it is a fact that JSON Array is wrapped in quotes which makes it a String primitive. You need to provide custom deserialiser for it, unwrap array from quotes and manually split items by comma (,). Example solution could look like below:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.ToString;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
List<Cluster> clusters = readClusters(jsonFile);
clusters.forEach(System.out::println);
}
private static List<Cluster> readClusters(File jsonFile) throws IOException {
Gson gson = new GsonBuilder().create();
try (Stream<String> lines = Files.lines(jsonFile.toPath())) {
return lines
.map(line -> gson.fromJson(line, Cluster.class))
.collect(Collectors.toList());
}
}
}
class ArrayAsStringJsonDeserializer implements JsonDeserializer<List<String>> {
#Override
public List<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String value = json.getAsString().trim();
value = value.substring(1, value.length() - 1);
return Arrays.stream(value.split(",")).map(String::trim).collect(Collectors.toList());
}
}
#Data
#ToString
class Cluster {
protected long id;
protected long size;
#SerializedName("cluster_size_in_offers")
protected long clusterSizeInOffers;
#JsonAdapter(ArrayAsStringJsonDeserializer.class)
#SerializedName("id_values")
protected List<String> idValues;
#SerializedName("categoryDensity")
protected int catDensity;
#SerializedName("category")
protected String cat;
}
Above code prints:
Cluster(id=2, size=4, clusterSizeInOffers=1, idValues=[814914023129, w2190254, pfl60gs25ssdr, pfl60gs25ssdr], catDensity=1, cat=Computers_and_Accessories)
Cluster(id=3, size=2, clusterSizeInOffers=1, idValues=[hst322440ss, g1042641], catDensity=1, cat=Office_Products)
Cluster(id=4, size=4, clusterSizeInOffers=1, idValues=[4051329063869, t24datr01765, t24datr01763, datr01763], catDensity=1, cat=Automotive)
...

how to get same fields from jsonArray

using gson, I parsed data in json format and now I need to extract the value "dt_txt" and their value "temp" from this data and I don’t understand how to pull and paste them into the collection where the key is "dt_txt" and its value is "temp "
The data that I received: https://imgur.com/a/qAxwEri
package testClassPackage;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class weatherParse {
public static void main(String[] args) throws IOException {
String sURL = "http://api.openweathermap.org/data/2.5/forecast/?q=Odessa,ua&APPID=518a64dd48106aa542464d3bd94d12ce"; //just a string
// Connect to the URL using java's native library
URL url = new URL(sURL);
URLConnection request = url.openConnection();
request.connect();
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
JsonArray message = rootobj.get("list").getAsJsonArray();
for (int i = 0; i < message.size(); i++) {
System.out.println();
}
System.out.println(message);
}
}
iterate over the JsonArray(message I changed to messages here) as JsonElement and get main object from the element then fetch th corresponding temp.
Map<String,String> data = new HashMap<>();
for(JsonElement lst : messages) {
JsonObject lstObject = lst.getAsJsonObject();
JsonObject el = (JsonObject) lstObject.get("main");
System.out.println(lstObject.get("dt_txt").getAsString() +" "+el.get("temp").getAsString());
data.put(lstObject.get("dt_txt").getAsString(), el.get("temp").getAsString());
}

How to replace "emailRecipients" key value from a json object in java

I need to replace emailRecipients value with some other value.
Here is JSON
{"payload": {"injectedDetails": "{\"injectedDetails\":\"test\"}","originalPayload": "{\"messageId\":\"232342",
\"emailRecipients\":[\"test#abc.com\"]}"},
"status": "OK"
}
I Tried below, but its putting a new key rather than replacing the existing once.even tried with putOnce()
jsonObjOriInj=new JSONObject(jsonobjectString);
jsonObjOriInj.put("emailRecipients", "2323");
Your JSON is not valid, but assuming JSON should be in following format,
{
"payload": {
"injectedDetails": {
"injectedDetails": "test"
}
},
"originalPayload": {
"messageId": "232342",
"emailRecipients":[
"test#abc.com"
]
},
"status": "OK"
}
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class Main {
public static void main(String[] args) throws ParseException {
String data = "{\"payload\":{\"injectedDetails\":{\"injectedDetails\":\"test\"}},\"originalPayload\":{\"messageId\":\"232342\",\"emailRecipients\":[\"test#abc.com\"]},\"status\":\"OK\"}";
JSONParser parser = new JSONParser();
JSONObject jsonObject = (JSONObject) parser.parse(data);
//get originalPayload object
JSONObject originalPayload = (JSONObject) jsonObject.get("originalPayload");
// create new json array
JSONArray newEmailRecipients = new JSONArray();
// add new email recipients
newEmailRecipients.add("updated_test#abc.com");
// update originalPayload object with new emailRecipients
originalPayload.put("emailRecipients", newEmailRecipients);
// update JSON with updates originalPayload object
jsonObject.put("originalPayload", originalPayload);
System.out.println(jsonObject);
}
}
Output:
{"payload":{"injectedDetails":{"injectedDetails":"test"}},"originalPayload":{"messageId":"232342","emailRecipients":"[updated_test#abc.com]"},"status":"OK"}

How to get values inside from an array which is inside of an object?

I want to get the values of latitude and longitude from the JSON, which consists of two objects "stoppage" & "routePlaceback", now I'm able to get data from "routePlaceback" only, but I have no clue how to get only the values of latitude and longitude? code is as follows,
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Iterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class Finder_Json
{
#SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception
{
// parsing JSON file
Object sampleFile_object = new JSONParser().parse(new FileReader("sample.json"));
// typecasting object to JSONObject
JSONObject sampleFile_JSONObject = (JSONObject) sampleFile_object;
JSONArray routePlaceback = (JSONArray) sampleFile_JSONObject.get("routePlaceback");
Iterator iterator_1 = routePlaceback.iterator();
while (iterator_1.hasNext())
{
System.out.println(iterator_1.next());
System.out.println("\n");
}
}
}
My sample.json file consists,
{
"stoppage":
[
{
"latitude": "23.074207",
"longitude": "72.557227",
"record_date": 1556217000,
"start_time": 1556217000,
"end_time": 1556304360,
"duration_time": 1456
}
],
"routePlaceback":
[
{
"distance": 0.36,
"longitude": "72.502385",
"ignition": 1,
"record_date": 1556303400,
"speed": 53.708,
"latitude": "23.034403"
},
{
"distance": 0.38,
"longitude": "72.506072",
"ignition": 1,
"record_date": 1556303430,
"speed": 25.927999,
"latitude": "23.034045"
}
]
}
This is what I get when I run the above code,
But my desired output is as,
23.034403, 72.502385
23.034045, 72.506072
You can extract the required values while displaying:
while (iterator_1.hasNext())
{
JSONObject obj = (JSONObject) iterator_1.next()l
System.out.println(obj.get("latitude")+" , "+obj.get("longitude"));
System.out.println("\n");
}
You are trying to access the property of an Object where you can get the Object.
while (iterator_1.hasNext())
{
JSONObject k= (JSONObject)iterator_1.next()
System.out.println(k.latitude+" "+k.longitude);
System.out.println("\n");
}
I modified a little bit your code to achieve your target. Please find the example below:
import java.io.FileReader;
import java.util.Iterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class Finder_Json
{
#SuppressWarnings("rawtypes")
public static void main(String[] args) throws Exception
{
// parsing JSON file
Object sampleFile_object = new JSONParser().parse(new FileReader("src/main/resources/sample.json"));
// typecasting object to JSONObject
JSONObject sampleFile_JSONObject = (JSONObject) sampleFile_object;
JSONArray routePlaceback = (JSONArray) sampleFile_JSONObject.get("routePlaceback");
Iterator iterator = routePlaceback.iterator();
while (iterator.hasNext()) {
JSONObject objt = (JSONObject) iterator.next();
System.out.println(objt.get("latitude") + ", " + objt.get("longitude"));
}
}
}
I strongly suggest to use Other libraries like GSON or Jackson anyway.

how to convert stringified JSONObject[] to JSONObj[] in java

I have JSONObject[] in stringified format. I need to convert it back to JSONObject[] in java how I can achive that??
Sample Code :
JSONObject[] json = new JSONObject[10];
String jsonStrArray = "[{a:1,b:2,c:3},{a:1,b:2,c:3},{a:1,b:2,c:3}]";
JsonParser parser = new JsonParser();
JsonObject jo = (JsonObject)
parser.parse(strFinalRecord).getAsJsonObject();
json = jo;
Error:
incompatible type
Required : org.json.JsonObject[]
Found : com.google.gson.JsonObject
If it is getting gson.JsonObject how to can I cast it to JsonObject[] ?
Please help me to resolve this issue
The json String you have created is not formatted correctly.
Try the following code.
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class JsonTest {
public static void main(String arg[]) throws ParseException {
JSONObject json = new JSONObject();
String jsonStrArray = "[{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"},{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"},{\"a\":\"1\",\"b\":\"2\",\"c\":\"3\"}]";
JSONParser parser = new JSONParser();
JSONArray jo = (JSONArray) parser.parse(jsonStrArray);
System.out.println(jo);
json.put("key", jo);
System.out.println(json);
}
}
Use JSON-Simple

Categories