How do I use fields from current json object and pass it to custom constructor of the next object. If I use default deserialization using gson, it works fine for the fields which have the same name, but since my room pojo has fields streetName and houseName(i want to store which house and street it belongs to), i want to add that while deserializing. How do I do this? I have a json which looks like this:
{
"database": {
"name": "",
"email": "",
"password": "",
"streets": {
"streetName1": {
"houseName1": {
"room1": {
"roomMembers": 3
}
},
"houseName2": {
"room2": {
"roomMembers": 2
}
}
},
"streetName2": {
"houseName3": {
"room3": {
"roomMembers": 1
},
"room4": {
"consumption": ""
}
}
}
}
}
}
My pojos are as follows:
Street.java
public class Street{
String streetName;
List<House> houseList;
///getters and setters
}
House.java
public class House{
String houseName;
String streetName; //this is what I want to set using a different constructor
List<Room> roomList;
///getters and setters
}
Room.java
public class Room{
String roomName;
String houseName;//this is what I want to set using a different
constructor
String streetName; //this is what I want to set using a different
constructor
int roomMembers;
///getters and setters
}
Related
I have this JSON and I want to generate objects with it.
{
"responseId": "response-id",
"session": "projects/project-id/agent/sessions/session-id",
"queryResult": {
"queryText": "End-user expression",
"parameters": {
"orderNumber": "PQL7648194AAAAA",
"lastName": "RIVERO"
},
"action": "order",
"allRequiredParamsPresent": true,
"intent": {
"name": "projects/project-id/agent/intents/intent-id",
"displayName": "[InfoVuelo] Dia-hora de salida - datos de orden"
},
"languageCode": "es"
},
"originalDetectIntentRequest": {}
}
The fields of "parameters" are variable. For example for one situation parameters could be
{
"parameters": {
"email":"example#example.com"
}
}
Also, I could have
{
"parameters": {
"orderNumber": "PQL7648194AAAAA",
"lastName": "RIVERO"
}
}
I made a class Parameters and 2 classes(OrderNumberAndLastNameParams and EmailParams) that extends Parameters
public class EmailParams implements Parameters {
private String email;
}
public class OrderNumberLastNameParams implements Parameters {
private String orderNumber;
private String lastName;
}
My method to create objects with a given JSON file
public static <T> T buildBodyFromJson(String filePath, Class<T> clazz) {
ObjectMapper myMapper = new ObjectMapper();
T jsonMapper = null;
try {
jsonMapper = myMapper.readValue(new ClassPathResource(filePath).getInputStream(), clazz);
} catch (IOException e) {
fail(e.getLocalizedMessage());
}
return jsonMapper;
}
But when I try to build the object, It tries to instantiate Parameter object instead of children objects getting "Unrecognized field ... not marked as ignorable ".
I'm understanding that you don't really need two separated classes, the problem is that you need to generate a requestbody with this object that doesn't have null / empty fields.
Well, there is an annotation that may help you.
Create a single class for paramters with all the 3 properties and annotate with #JsonInclude(JsonInclude.Include.NON_EMPTY)
#JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Parameters {
private String email;
private String orderNumber;
private String lastName;
}
This annotation makes empty or null fields to not appears on the requestbody that you're creating.
In some incoming JSON there is a list
"age" : 27,
"country", USA,
"fields": [
{
"id": 261762251,
"value": "Fred"
},
{
"id": 261516162,
"value": "Dave"
},
]
I know the key int for what I am looking for [261762251].
I would like to map that to a plain String field firstname in the User object with the rest of the bottom level fields from the JSON. I have tried extending com.fasterxml.jackson.databind.util.StdConverter and adding the annotation #JsonSerialize(converter=MyConverterClass.class) to the variable in the User class with no luck.
My architecture is like this:
public class User {
private String age;
private String country;
private String firstname; // this is the field in the list that needs converting
// getters and setters
}
public class ApiClient{
public User getUsers(){
Response response;
//some code to call a service
return response.readEntity(User.class)
}
}
What is the best approach to achieve this?
You can try something like below:
class Tester
{
public static void main(String[] args) throws Exception {
String s1 = "{\"fields\": [ { \"id\": 261762251, \"value\": \"Fred\" }, { \"id\": 261516162, \"value\": \"Dave\" }]}";
ObjectMapper om = new ObjectMapper();
Myclass mine = om.readValue(s1, Myclass.class);
System.out.println(mine);
}
}
public class User {
private String age;
private String country;
private String firstname; // this is the field in the list that needs converting
#JsonProperty("fields")
private void unpackNested(List<Map<String,Object>> fields) {
for(Map<String,Object> el: fields) {
if((Integer)el.get("id") == 261762251) {
firstname = el.toString();
}
}
}
// getters and setters
}
My Spring Boot app makes a call to a REST API and receives a JSON with a varying number of entities. E.g.
{
"content": {
"guest_1": {
"name": {
"firstName": "a",
"lastName": "b"
},
"vip": false
},
"guest_2": {
"name": {
"firstName": "c",
"lastName": "d"
},
"vip": false
},
...more guests omitted...
}
}
There can be 1 to many guests and I don't know their number upfront. As you can see, they aren't in an array, they are objects instead.
I'd like to avoid deserializing into a class like
public class Content {
#JsonProperty("guest_1")
private Guest guest1;
#JsonProperty("guest_2")
private Guest guest2;
// More Guests here each having their own field
}
What I'd like to use is
public class Content {
private List<Guest> guests;
}
The #JsonAnySetter annotation I read about at https://www.baeldung.com/jackson-annotations looks promising but I couldn't get it to work.
3.2. Convert to an object at https://www.baeldung.com/jackson-json-node-tree-model looks also good but it didn't work out either.
I'm not sure if I can make Jackson do this in a declarative way or I should write a custom JsonDeserializer. Could you please help me?
#JsonAnySetter will work as it allows to specify a POJO type as second parameter. You could recreate the example JSON as, omitting setXXX() and getXXX() methods on POJOs for clarity:
private static class Content {
private Guests content;
}
private static class Guests {
private List<Guest> guests = new ArrayList<>();
#JsonAnySetter
private void addGuest(String name, Guest value) {
guests.add(value);
}
}
private static class Guest {
private Name name;
private boolean vip;
}
private static class Name {
private String firstName;
private String lastName;
}
With your JSON example will produce:
Content root = new ObjectMapper().readValue(json, Content.class);
root.getContent().getGuests().stream()
.map(Guest::getName)
.map(Name::getFirstName)
.forEach(System.out::println); // a, c
i want to parse Json with this format:
{"data": {
"user": {
"edge_follow": {
"count": 2554, "page_info": {
"node": {
"id": "5719761315", "username": "disneyangell" ...
"node": {
"id": "2260368333", "username": "moosa_sedaghat",...
"node": {
"id": "3982701506", "username": "alidadashi512", ...
.
.
.
from this link ;
i got my pojos from www.jsonschema2pojo.org/
i tried GsonConverter and Jackson ObjectMapper also
the problem is parsed object's node list is empty or it's zero always.
how to solve this?
if i need to use CustomConverter write that for this case.
So to get the JSON you want you have to be logged in to instagiam. Otherwise you will get an empty "edges" object in the JSON returned from your get request. If you are logged in here is an example to do it with Gson:
The POJO (maybe you need to add getter methods for fields you are interested in):
public class FollowJson{
Data data;
String status;
public ArrayList<FollowNode> getFollowNodes(){
return data.getFollowNodes();
}
class Data{
User user;
public ArrayList<FollowNode> getFollowNodes(){
return user.getFollowNodes();
}
}
class User{
EdgeFollow edge_follow;
public ArrayList<FollowNode> getFollowNodes(){
return edge_follow.getFollowNodes();
}
}
class EdgeFollow{
Integer count;
ArrayList<OuterNode> edges;
HashMap<String, Object> page_info;
public ArrayList<FollowNode> getFollowNodes(){
ArrayList<FollowNode> bufList = new ArrayList<FollowNode>();
for(OuterNode outer : edges){
bufList.add(outer.getNode());
}
return bufList;
}
}
class OuterNode{
FollowNode node;
public FollowNode getNode(){
return node;
}
}
class FollowNode {
Boolean followed_by_viewer;
String full_name;
String id;
Boolean is_verified;
String profile_pic_url;
Boolean requested_by_viewer;
String username;
public Boolean getFollowedStatus(){
return followed_by_user;
}
public String getId(){
return id;
}
public String getUsername(){
return username;
}
}
}
Then pass the POJO.class and the JSON string to the Method:
public <T> T getJsonFromString(String jsonString, Class<T> var){
GsonBuilder builder = new GsonBuilder();
return builder.create().fromJson(jsonString, var);
}
You can then call getFollowNodes() on the returned object, which returns an array of objects (FollowNode) representing the "nodes" in the JSON.
My JSON lokes something like this:
{
"people":
{
"stuff":"OK",
"name":"some reason",
"content" :
{
"name": "pet",
"phone": "some value",
"owner": "123"
}
},
"machines":
{
"owner":
{
"id": "123",
"name": "peter"
}
}
}
My owner class looks like this:
public class Owner {
#Expose
private String id;
#Expose
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I get this error: Expected BEGIN_OBJECT but was STRING
I made a pojo for the owner, but my problem is that the owner on hierarchy level 3 is only a String and on lower levels it is a custom object. How can i tell my parser to handle the owner object starting from the third level different than before ?
Use the google Gson parser lob to create the java object from the jSON
http://www.javacreed.com/simple-gson-example/
http://www.journaldev.com/2321/google-gson-api-for-json-processing-example-tutorial
ok i just created another Pojo with the same name + '_' one pojo contains the owner as String and one as owner object. was more easy than expected, there was no parsing neccesarry