Deserializing JSON objects with variable structure, GSON - json

I'm trying to deserialize JSON with the following structure using GSON:
"FKeyColumn": [{
"ForeignKeyColumns": {
"Id": "Id"
},
"ReferenceTable": "Expense_Group_Configurations"
}],
"FKeyColumn": [{
"ForeignKeyColumns": {
"Vid": "Id"
},
"ReferenceTable": "Expense_Group_Configurations"
}]
...
I'm not sure how to structure my ForeignKeyColumns class though, since the JSON object it represents contains arbitrary key-value pairings (there's no set structure aside from the object always being named ForeignKeyColumns). How can I parse this with GSON?

It required a custom deserializer for FKeyColumn objects:
public class FKeyColumnDeserializer implements JsonDeserializer<FKeyColumn> {
public FKeyColumn deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
throws JsonParseException {
final JsonArray jsonFKArray = json.getAsJsonArray();
final FKeyColumn fkc = new FKeyColumn();
for (int i = 0; i < jsonFKArray.size(); i++) {
final JsonObject fkObject = (JsonObject) jsonFKArray.get(i);
final String ReferenceTable = fkObject.get("ReferenceTable").getAsString();
final JsonObject ForeignKeyColumns = (JsonObject) fkObject.get("ForeignKeyColumns");
Set<Entry<String, JsonElement>> entrySet = ForeignKeyColumns.entrySet();
for(HashMap.Entry<String, JsonElement> entry : entrySet){
fkc.fkRefTableMap.put(entry.getKey(), ReferenceTable);
}
}
return fkc;
}
}

Related

How to check the input string present in json array using json path

I am trying to check the given input string is present in a json array. Below is my sample json
{
"school": {
"class": {
"standard": "6",
"student_list": [
"Daniel",
"Jack",
"John"
]
}
}
}
Let say i am trying to find a given input name is part of student_list if the given input name matches then it should retrieve the complete details of the class. Let say i am passing name 'John' it should give me below result
{
"standard": "6",
"student_list": [
"daniel",
"jack",
"john"
]
}
I am using jayway json path library i tried couple of ways like below
$.school.class.[?('john' anyof #.student_list)]
$.school.class.[?(#.'john' anyof #.student_list)]
But every time it is giving me empty array. I am new to jsonpath query could you please point me where i am going wrong or help me what is wrong with my json path query.
The comparison is case sensitive.
Filter Operator anyof -- left has an intersection with right [?(#.sizes anyof ['M', 'L'])]
Indefinite paths always returns a list
Change your query to
$.school.class[?(#.student_list anyof ['John'])]
OR
$.school.class[?(#.student_list contains 'John')]
OR
$.school.class[?('John' in #.student_list)]
Here click for git repo is the code to check JSON object is present in whole JSON object:
private static Map<String, Object> getJsonMapFlatten(String json) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
MapType type = mapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class);
Map<String, Object> map = mapper.readValue(json, type);
return JsonMapFlattener.flatten(map);
}
public static void getJsonValue(String json, String keyName) throws JsonProcessingException {
Map<String, Object> map = getJsonMapFlatten(json);
Iterator<Map.Entry<String, Object>> itr = map.entrySet().iterator();
while (itr.hasNext()) {
Map.Entry<String, Object> obj = itr.next();
if (obj.getKey().contains(keyName)) {
System.out.println(obj.getKey() + "==>" + obj.getValue());
}
}
}
public static void validateJson(String json, String jsonToCompare) throws JsonProcessingException {
Map<String, Object> flattenJsonResponse = getJsonMapFlatten(json);
Map<String, Object> flattenResponseToCompare = getJsonMapFlatten(jsonToCompare);
List<String> jsonResponsePaths = getJsonPaths(flattenJsonResponse);
List<String> responsePathsToCompare = getJsonPaths(flattenResponseToCompare);
if (flattenJsonResponse.size() >= flattenResponseToCompare.size()) {
for (String jsonPath : responsePathsToCompare) {
if (isPathPresent(jsonResponsePaths, jsonPath)) {
System.out.println("path present: " + jsonPath);
System.out.println(getPath(jsonResponsePaths, jsonPath));
System.out.println(flattenResponseToCompare.get(jsonPath) + "<==>" + flattenJsonResponse.get(getPath(jsonResponsePaths, jsonPath)));//store the values
} else {
System.out.println("path is not present: " + jsonPath);
}
}
} else {
for (String jsonPath : jsonResponsePaths) {
if (isPathPresent(responsePathsToCompare, jsonPath)) {
System.out.println(flattenJsonResponse.get(jsonPath) + "==" + flattenResponseToCompare.get(getPath(responsePathsToCompare, jsonPath)));
} else {
System.out.println("path is not present: " + jsonPath);
}
}
}
}
private static List<String> getJsonPaths(Map<String, Object> map) {
List<String> list = new ArrayList<>();
Iterator<String> itr = map.keySet().iterator();
while (itr.hasNext()) {
list.add(itr.next());
}
return list;
}
private static boolean isPathPresent(List<String> paths, String path) {
for (String list : paths) {
if (list.contains(path)) {
return true;
}
}
return false;
}
private static String getPath(List<String> paths, String path) {
for (String list : paths) {
if (list.contains(path)) {
return list;
}
}
throw new NullPointerException("No such path exist " + path);
}

ServiceStack: How do I Serialize a nested object of Dictionary<string, object>?

"event-data":
{
"event": "opened",
"timestamp": 1529006854.329574,
"id": "DACSsAdVSeGpLid7TN03WA",
"delivery-status": {
"title": "success"
}
}
//Structure
public List<Dictionary<string, object>> EventData { get; set; } = new List<Dictionary<string, object>>();
var json = ServiceStack.Text.JsonSerializer.SerializeToString(request.EventData);
So clearly this Jsonifies the object, but only at the root level. Every child object becomes riddled with \n and \t escapes... so it's just flat stringing the children.
What's the proper (Fastest) way to make this just raw nested Json?
You can use the late-bound generic Dictionary<string, object> and List<object>, e.g:
var obj = new Dictionary<string, object> {
["event-data"] = new Dictionary<string, object> {
["event"] = "opened",
["timestamp"] = 1529006854.329574,
["id"] = "DACSsAdVSeGpLid7TN03WA",
["delivery-status"] = new Dictionary<string,object> {
["title"] = "success"
}
}
};
obj.ToJson().IndentJson().Print();
Prints out:
{
"event-data": {
"event": "opened",
"timestamp": 1529006854.329574,
"id": "DACSsAdVSeGpLid7TN03WA",
"delivery-status": {
"title": "success"
}
}
}
When in doubt, you can use JS Utils to parse any arbitrary JSON which will parse them in late-bound generic collections:
var dto = JSON.parse(json);
dto.ToJson().IndentJson().Print();
Note: JS Utils is better at deserializing unknown JSON whilst ServiceStack.Text JSON Serializer is better about deserializing into typed POCOs.

get field list from json object list with Jackson

I have JSON data that is getting from api, I want to get list of a field inside of json data.
JSON data :
[
{
"code":"en",
"native":true,
"plurals":{
"length":2,
"forms":[
"one",
"other"
]
}
}, {
"code":"de",
"native":true,
"plurals":{
"length":2,
"forms":[
"one",
"other"
]
}
}, {
"code":"le",
"native":true,
"plurals":{
"length":2,
"forms":[
"one",
"other"
]
}
}
]
I want to get code fields data as list<String> like below :
["en","de","le"]
what is the easiest way to do this?
Note : I am using Spring's RestTemplate to get data.
Use the findValues method to extract the value of all properties named "code":
ObjectMapper om = new ObjectMapper();
JsonNode tree = om.readTree(json);
List<JsonNode> code = tree.findValues("code");
Running it on your example data gives the result
["en", "de", "le"]
Try below method.
public static void main(String[] args) throws JSONException {
String jsonString = jsonResponseFromApi;
JSONObject obj= new JSONObject();
JSONObject jsonObject = obj.fromObject(jsonString);
ArrayList<String> list = new ArrayList<String>();
for(int i=0; i<jsonObject.length(); i++){
list.add(jsonObject.getJSONObject(i).getString("code"));
}
System.out.println(list);
}
}
Refer below thread for more details How to Parse this JSON Response in JAVA

depending on input json array return output json in literal json in spring mvc

My controller
#Controller
public class HomeController {
#RequestMapping(value = "/trans", method = RequestMethod.POST)
public #ResponseBody String jsontest(#RequestBody String transjson) throws JsonProcessingException, IOException, JSONException {
try{
JsonParser parser = new JsonParser();
parser.parse(transjson);
String output = null;
JSONObject obj1 = new JSONObject(transjson);
int size=obj1.getJSONArray("inArray").length();
/* this is where I need help.*/
for(int i=0;i<size;i++){
output="{\"outArray\":[{\"in\":\""+obj1.getJSONArray("inArray").get(i)+"\",\"out\":\"hie\"}]}";
}
return output;
}
catch(JsonSyntaxException ex)
{
System.out.println(ex.getMessage());
return "{\"message\":\"Invalid JSON\"}";
}
catch(Exception ex)
{
System.out.println(ex.getMessage());
return "{\"message\":\"Exception occured\"}";
}
}
}
what I want is if my input JSON is
{
"inArray": [
"first"
]
}
then my output should be
{
"outArray": [
{
"in": "first",
"out": "hie"
}
]
}
if my input JSON is
{
"inArray": [
"first",
"second"
]
}
then my output should be
{
"outArray": [
{
"in": "first",
"out": "hie"
},
{
"in": "second",
"out": "hie"
}
]
}
means I don't know the number of the elements in the input array in the input json. And i need make my output in the literal json format on the basis of input elemen numbers as shown above.
I tried few things but have not been able to get the desired output.
I have been able to do this.
Actually I was trying to make string object but instead of that if I make jsonobject and put everything in it and at last return that jsonobject.tostring() form then the desired resultcan be obtained.
int size=obj1.getJSONArray("inArray").length();
JSONArray ja = new JSONArray();
for(int i=0;i<size;i++){
JSONObject jo = new JSONObject();
jo.put("in", obj1.getJSONArray("inArray").get(i));
jo.put("out", "hie");
ja.put(jo);
}
JSONObject mainObj = new JSONObject();
mainObj.put("outArray", ja);
return mainObj.toString();

How can I use the Gson to parse a json that keep the same key but not the same type

Actually,I want to parse the json like this:
{
"contents": [
{
"type": "image",
"data": {
"attachment": "picurl",
"width": 600,
"height": 398
}
},
{
"type": "text",
"data": "something like xxx"
}
]
}
as you can see, the key "data" sometimes is a String, and sometings is json object, what should I do to parse this json by Gson?
The way I do this is deserialize twice. First into an class that defines only type.
class TypeObject {
public String type;
}
After the first deserializiation, you can read the type, and discover which is the real target object you should deserialize into.
De-serializing twice obviously isn't ideal, but that's the unfortunate nature of using a static language to de-serialize a JSON string with non uniform objects in a list.
I have find the way the parse that json, as Alexis C said, I custom a deserializer, like that
#Override
public MessageDiv deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
MessageDiv messageDiv = new MessageDiv();
JsonObject obj = jsonElement.getAsJsonObject();
String msgtype = obj.get("type").getAsString();
messageDiv.setType(msgtype);
if (msgtype.equals("text")) {
messageDiv.setContent(obj.get("data").getAsString());
} else {
JsonObject imgObj = obj.get("data").getAsJsonObject();
DivData dd = new DivData();
dd.setAttachment(imgObj.get("attachment").getAsString());
dd.setHeight(imgObj.get("height").getAsInt());
dd.setWidth(imgObj.get("width").getAsInt());
messageDiv.setData(dd);
}
return messageDiv;
}
About how to custom o deserializer, click here, it's userful for me!