Map dynamic JSON data to pojo class in Java? - java

I am creating a crud form in which I am producing and consuming Json data.
Problem:
Json data I am producing is very dynamic. So I don't know how to map it to my pojo class.
What I have tried
1) Using jackson library, I created structure of my json data and
tried mapping with it. It failed as in data "**Keys**" are dynamic so mapping failed.
2) I searched and found JsonNode provided by Jackson, problem with
this is my json structure has key:[{},{}] structure like this
**key-->array of objects**, so I tried parsing it with json node but failed.
My Json Data
Type 1
{
"city_master": [
{
"citycode": [
"100",
"1130385"
]
},
{
"cityname": [
"London",
"1130383"
]
},
{
"statecode": [
"512",
"1130382"
]
}
]
}
Problem with structure is that key = "city_master" or any key in this format eg("citycode", "cityname" etc) is dynamic so can't create mapping pojo for this class.
Then I tried fixing the outer key as root and parse is as Json Node as
Type 2
{
"root": [
{
"citycode": [
"100",
"1130385"
]
},
{
"cityname": [
"London",
"1130383"
]
},
{
"statecode": [
"512",
"1130382"
]
}
]
}
In this structure I loose my key value, but I can store it else where.
With JsonNode (Type-2) I tried this
String jsonString = tdObj.getTempData(); // return's Json String
TempDataTblPojo obj = new ObjectMapper().readValue(jsonString, TempDataTblPojo.class);
JsonNode jsonNode = obj.getRoot();
System.out.println("Name = " + jsonNode);
This class TempDataTblPojo
public class TempDataTblPojo {
private JsonNode root;
public JsonNode getRoot() {
return root;
}
public void setRoot(JsonNode root) {
this.root = root;
}
}
It prints this
Name = [{"citycode":["100","1130385"]},{"cityname":["London","1130383"]},{"statecode":["512","1130382"]}]
Now how to parse this JsonNode, to get all this key-value's? Or is there is efficient or much more cleaner solution, I will be happy to accept.

Maybe this will help you.
class Pojo {
private List<PojoItem> root;
public List<PojoItem> getRoot() {
return root;
}
public void setRoot(List<PojoItem> root) {
this.root = root;
}
}
class PojoItem {
private Map<String, List<String>> items = new HashMap<>();
public Map<String, List<String>> getItems() {
return items;
}
#JsonAnySetter
public void setItem(String key, List<String> values) {
this.items.put(key, values);
}
}
And then you can get it from json using this:
Pojo result = objectMapper.readValue(json, Pojo.class);

Related

How to parse "[ "a", [ "adidas", "acb", "amazon" ] ] to object java?

I can't converter this response api "[ "a", [ "adidas", "acb", "amazon" ] ] to object java or kotlin
The format of your JSON data is not very suitable to convert to a java object directly,try to make your JSON data like this:
{"a": ["adidas", "acb", "amazon"] }
or
{"keyA" : "a", "keyB" : ["adidas", "acb", "amazon"] }
But it's still depends on what is your actual demand
You can test your JSON data here:
JSON to JAVA Converter live
May be this example can help you.
public class Test {
public static void main(String... args) throws Exception {
String json = "[ "a", [ "adidas", "acb", "amazon" ] ];
// Now do the magic.
Data data = new json().fromJson(json, Data.class);
// Show it.
System.out.println(data);
}
}
class Data {
private String data;
private List<String> groups;
public String getData() { return data; }
public void setData(String data) { this.data= data; }
public List<String> getGroups() { return groups; }
public void setGroups(List<String> groups) { this.groups = groups; }
}

I want to extract a value from a json

I want to extract a key and its value from json object. I am having a 3 objects in a json with parent child relation, named as
1. Parent,
2. childOne_OfParent and
3. child_OF_childOne.
I want to extract all the value of "userQueryId" from child_OF_childOne and store into a string type variable.
How do I perform this. Thanks in advance.
My Json object is:
{
"createdBy": "****",
"dashboardId": 1,
"childOne_OfParent": [
{
"createdBy": null,
"dashboardSectionId": 1,
"child_OF_childOne": [
{
"createdBy": "XYZ",
"userQueryId": "283"
},
{
"createdBy": "ABC",
"userQueryId": "284"
},
{
"createdBy": "AWS",
"userQueryId": "285"
}
]
}
]
}
You can use the json to create a model java class like this. I used your json to create the class using the site https://codebeautify.org/json-to-java-converter. You can give a classname of your choice in the Class_Name.
public class Class_Name {
private String createdBy;
private float dashboardId;
ArrayList < Object > childOne_OfParent = new ArrayList < Object > ();
// Getter Methods
public String getCreatedBy() {
return createdBy;
}
public float getDashboardId() {
return dashboardId;
}
// Setter Methods
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public void setDashboardId(float dashboardId) {
this.dashboardId = dashboardId;
}
}
Then you can use the Jackson to convert your json into a java object and access the data you want. Here jsonString is your json and the objResp is your object.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Class_Name objResp = mapper.readerFor(Class_Name.class).readValue(jsonString);
Here is a useful guide for that. https://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
The tool for these kind of tasks is JsonPath. It has xpath-like search capabilities.
Here is a working example of the given question
public static void main(String[] args) {
String searchQueryIds = "$.childOne_OfParent[*].child_OF_childOne[*].userQueryId";
try (InputStream is = Files.newInputStream(Paths.get("c:/temp/test.json"))) {
List<String> ids = JsonPath.parse(is).read(searchQueryIds);
System.out.println(ids);
} catch (Exception e) {
e.printStackTrace();
}
}
Assuming there is pojo for json and jackson library available. It will return comma separated queryUserIds.
Parent parent = new ObjectMapper().reader(Parent.class).readValue(inputJson);
String userIds = parent.getChildOne_OfParent().get(0).getChild_OF_childOne().stream()
.map(c -> c.getuserQueryId())
.collect(Collectors.joining(","));

How can I make reference handling syntax from Jackson and JSON.net compatible?

I have a server that produces the following JSON with Jackson.
{
"$id" : 1,
"employees" : [
{
"$id" : 2,
"name" : "John Rambo",
},
2 // Jackson: reference by ID only
]
}
The list of employees contains the same employee twice. Jackson correctly references the object by it's ID the second time.
I want to deserialize this in a client that uses JSON.net, but this won't work because JSON.net expects me to have the reference wrapped in a json object with a $ref property like this:
{
"$id": "1",
"employees" : [
{
"$id": "2",
"name": "John Rambo"
},
{
"$ref": "2" // JSON.net: reference wrapped in JSON object
}
]
}
Is there a way to make JSON.net correctly consume the Jackson syntax either by configuration or by implementing a custom deserializer?
Here's a custom converter that should work:
public class EmployeeConverter : JsonConverter
{
public override void WriteJson(
JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(
JsonReader reader,
Type objectType,
object existingValue,
JsonSerializer serializer)
{
List<Employee> employees = null;
if (reader.TokenType == JsonToken.StartArray)
{
JArray arr = serializer.Deserialize<JArray>(reader);
employees = new List<Employee>(arr.Count);
var employeeMap = new Dictionary<int, Employee>();
foreach (var item in arr)
{
if (item.Type == JTokenType.Object)
{
var employee = item.ToObject<Employee>();
employees.Add(employee);
int id = item["$id"].ToObject<int>();
employeeMap.Add(id, employee);
}
else if (item.Type == JTokenType.Integer)
{
Employee employee = null;
int id = item.ToObject<int>();
if (employeeMap.TryGetValue(id, out employee))
{
employees.Add(employee);
}
}
}
}
return employees;
}
public override bool CanRead
{
get { return true; }
}
public override bool CanConvert(Type objectType)
{
return false;
}
}
... and here's how you'd use it:
public class Company
{
public Company()
{
this.Employees = new List<Employee>();
}
[JsonConverter(typeof(EmployeeConverter))]
public List<Employee> Employees { get; set; }
}
Example: https://dotnetfiddle.net/XooyQC
Basically use a custom converter to deserialize the entire array. First, deserialize the array to a JArray, then inspect each element of the JArray to see if it's a reference or a new object.

render a simple static JSON response using Play! and Java

I have this function to return a valid JSON response:
public static Result response() {
ObjectNode result = Json.newObject();
result.put("status", "OK");
result.put("response", "Hello ");
return ok(result);
}
But what I want is to server an Array of objects in "result" property like:
{
"status": "OK",
"response": {
"results": [
{
"key1": "value",
"key2": 90,
"key3": "value"
},
{
"key1": "value"
"key2": 90,
"key3": "value",
}
]
}
}
How can I do this? I need to use Java and Play!
The Play framework uses Jackson. Therefore, you may use Jackson proper:
private static final JsonNodeFactory NODE_FACTORY = JsonNodeFactory.instance;
// ...
final ArrayNode results = NODE_FACTORY.arrayNode();
ObjectNode oneResult;
oneResult = NODE_FACTORY.objectNode(); // or Json.newObject();
oneResult.put(...); // etc
results.add(result);
//rinse, repeat for all other result objects, then:
result.put("results", results);
I guess the Json class also has .newArray() and such. Have a look at Jackson's ObjectNode, ArrayNode. Note: as far as I can remember, Play uses Jackson 1.9.x, which is prehistoric...
But really, you should try and use Jackson's {de,}serialization.
I did not wait for your answer about what is Play!, so I write based on Gson.
Try use this class:
public class Result implements Serializable {
String status;
Response response;
class Response implements Serializable {
List<ListItem> results;
class ListItem implements Serializable {
String key1;
Integer key2;
String key3;
}
}
}
It 100% works on your json fragment. You can supplement it with the necessary fields.
And then you can use Gson:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Result result = gson.fromJson(new FileReader(new File("json.json")), Result.class);
String json = gson.toJson(result);
System.out.println(json);
Prints:
{
"status": "OK",
"response": {
"results": [
{
"key1": "value",
"key2": 90,
"key3": "value"
},
{
"key1": "value",
"key2": 90,
"key3": "value"
}
]
}
}
Try in this direction.
How about returning an ArrayNode in the result, like:
public static Result foo() {
ArrayNode arrayNode = Json.newObject().putArray("bars");
arrayNode.add("hello");
arrayNode.add("world");
return ok(arrayNode);
}

Jackson json arraylist of unknown fields

I have a JSON string like this:
{
"123": {
"hi": {
"name": "John",
"phone": "12345"
}
},
"124": {
"hi": {
"name": "James",
"phone": "12345"
}
},
"125": {
"hi": {
"name": "Leo",
"phone": "12347"
}
}
}
The JSON is ordered externally: 123, 124, 125 I just want to get the value of the last field ("125" : {...}) but I don't know its name, is auto-generated. What's the best way?
I'm trying mapping to an arrayList of JsonNodes, but I don't find the right way.
You can also do it using #JsonAnySetter annotation. Please, see below example. POJO class:
class Node {
private Integer key = Integer.MIN_VALUE;
private JsonNode value;
#JsonAnySetter
public void set(String newKey, JsonNode newValue) {
if (Integer.valueOf(newKey) > key) {
value = newValue;
}
}
public JsonNode getValue() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}
Example usage:
ObjectMapper mapper = new ObjectMapper();
Node node = mapper.readValue(json), Node.class);
System.out.println(node);
Prints:
{"hi":{"name":"Leo","phone":"12347"}}
I did it putting the JSON string in a JsonNode, data and mapping to a NavigableMap.
NavigableMap<String, JsonNode> updates = mapper.readValue(data.traverse(), new TypeReference<TreeMap<String, JsonNode>>() {});
Entry<String, JsonNode> lastEntry = updates.lastEntry();
String lastUpdate = lastEntry.getValue().toString();

Categories

Resources