Unable to deserialize JSON response into Java Objects - java

I know there are lots of queries on this topic but nothing has been helpful for me to resolve below issue
{
"_embedded": {
"customers": [
{
"id": 101,
"name": "John",
"city": "Ohio"
},
{
"id": 102,
"name": "Tom",
"city": "London"
}
]
}
}
for this I have created below Java objects:
#Data
public class Wrapper {
#JsonProperty("_embedded")
private Customers customer;
}
#Data
public class Customers {
#JsonProperty("customer")
private List<Foo> obj;
}
#Data
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Foo{
private int id;
private String name;
private String city;
}
Any help will be greatly appreciated.

You have some naming issues in your original question, but disregarding that, you could structure your classes according to the JSON to make it easier for both yourself and Gson.
Something like this would work:
public class JsonWrapper {
public Embedded _embedded;
}
public class Embedded {
public Customers customers;
}
public class Customers extends ArrayList<Foo>{ }
public class Foo{
public int id;
public String name;
public String city;
}
String json = "{\"_embedded\":{\"customers\":[{\"id\":101,\"name\":\"John\",\"city\":\"Ohio\"},{\"id\":102,\"name\":\"Tom\",\"city\":\"London\"}]}}";
JsonWrapper wrapper = new Gson().fromJson(json, JsonWrapper.class);

Related

Jackson-databind mapping JSON skip layer

I got a JSON response like this:
{
"status": "success",
"response": {
"entries": [
{
"id": 1,
"value": "test"
},
{
"id": 2,
"value": "test2"
}
]
}
}
And i want to map it with jackson-databind on an object like this:
public class Response {
#JsonProperty("status")
private String status;
#JsonProperty("response.entries")
private Collection<ResponseEntry> entries;
}
So i'm searching for an way to give #JsonProperty a path so it can skip the layer "response".
Welcome to Stack Overflow. You can define a wrapper class for your Collection<ResponseEntry> collection like below :
public class ResponseWrapper {
#JsonProperty("entries")
private Collection<ResponseEntry> entries;
}
The ResponseEntry class could be defined like below :
public class ResponseEntry {
#JsonProperty("id")
private int id;
#JsonProperty("value")
private String value;
}
Once defined these classes you can rewrite your old Response class like below :
public class Response {
#JsonProperty("status")
private String status;
#JsonProperty("response")
private ResponseWrapper responseWrapper;
}
You can flatten using the #JsonUnwrapped annotation.
You can have your classes like this
public class Response {
private String status;
private Collection<ResponseEntry> entries;
}
public class ResponseEntry {
#JsonUnwrapped
private Entry entry;
}
pubic class Entry{
private Integer id;
private String value;
}

How to avoid too many classes in jackson Java?

I have JSON serialization and deserialization is done using Jackson in java.
I have so many JSON fields that to serialize and deserialize I have multiple single-member classes, is there any better way to do this?
I don't have any limitations on using Jackson library, that is the library I have used for most of my cases.
public class Data{
public String type;
public int id;
public Attributes attributes;
public Relationships relationships;
}
public class Category{
public Data data;
}
public class Service{
public Data data;
}
public class Priority{
public Data data;
}
public class Status{
public Data data;
}
public class User{
public Data data;
}
public class Relationships{
public Category category;
public Service service;
public Priority priority;
public Status status;
public User user;
}
public class Root{
public Data data;
}
My sample JSON for which I am serializing looks like below.
{
"data": {
"id": 111,
"type": "op type",
"attributes": {
"title": "Some title"
},
"relationships": {
"category": {
"data": {
"type": "category",
"id": 1
}
},
"service": {
"data": {
"type": "service",
"id": 3
}
},
"priority": {
"data": {
"type": "priority",
"id": 1
}
},
"status": {
"data": {
"type": "status",
"id": 3
}
},
"user": {
"data": {
"type": "user",
"id": 3
}
}
}
}
}
Because Category, Service and others have the same fields data, if you create class manually, you can just create one common class DataWrapper. But I also see you said you use jsonschema2pojo rather than create class manually.
public class Data{
public String type;
public int id;
public Attributes attributes;
public Relationships relationships;
}
public class DataWrapper {
public Data data;
}
public class Relationships{
public DataWrapper category;
public DataWrapper service;
public DataWrapper priority;
public DataWrapper status;
public DataWrapper user;
}
public class Root{
public Data data;
}

How to update MongoDB #DbRef embedded collection?

So, I am trying my hands-on MongoDB CRUD operations using spring-data-mongodb. Below are my model classes,
#Document(collection = "alumni_students")
public class AlumniStudent {
#Id
private String id;
private String firstName;
private String lastName;
private String email;
#DBRef
private AlumniDepartment alumniDepartment;
#DBRef
private List<AlumniSubject> alumniSubjects;
... getters/setters
#Document(collection = "alumni_department")
public class AlumniDepartment {
#Id
private String id;
private String departmentName;
private String location;
... getters/setters
#Document(collection = "alumni_subjects")
public class AlumniSubject {
#Id
private String id;
private String subjectName;
private int marks;
... getters/setters
I am using MongoRepository for individual collections for their operations like below,
#Repository
public interface AlumniStudentRepository extends MongoRepository<AlumniStudent, String> { }
#Repository
public interface AlumniDepartmentRepository extends MongoRepository<AlumniDepartment, String> {}
#Repository
public interface AlumniSubjectRepository extends MongoRepository<AlumniSubject, String> {}
I have so far done good while creation and getting the student details. The issue I am facing is while updating the student data. In that also specifically while updating the data, I am confused as hell.
Below is my update code from service layer,
#Autowired
AlumniStudentRepository alumniStudentRepo;
#Autowired
AlumniDepartmentRepository alumniDeptRepo;
#Autowired
AlumniSubjectRepository alumniSubjRepo;
public AlumniStudent updateStudent(AlumniStudent student, String id) {
Optional<AlumniStudent> fetchedStudent = alumniStudentRepo.findById(id);
**// UPDATE STUDENT DATA, WORKS FINE**
if (fetchedStudent.isPresent()) {
AlumniStudent studentFromDB = fetchedStudent.get();
studentFromDB.setFirstName(student.getFirstName());
studentFromDB.setLastName(student.getLastName());
studentFromDB.setEmail(student.getEmail());
**// UPDATE DEPARTMENT DATA, WORKS FINE**
if (student.getAlumniDepartment() != null) {
Optional<AlumniDepartment> deptData = alumniDeptRepo.findById(studentFromDB.getAlumniDepartment().getId());
if (deptData.isPresent()) {
AlumniDepartment alumniDepartment = deptData.get();
alumniDepartment.setDepartmentName(student.getAlumniDepartment().getDepartmentName());
alumniDepartment.setLocation(student.getAlumniDepartment().getLocation());
alumniDeptRepo.save(alumniDepartment);
studentFromDB.setAlumniDepartment(alumniDepartment);
}
}
**// UPDATE SUBJECTS ARRAY DATA.... HOW TO DO THIS?**
if (student.getAlumniSubjects() != null && !student.getAlumniSubjects().isEmpty()) {
// Problematic area. How to perform update of arraylist here?
}
return alumniStudentRepo.save(studentFromDB);
}
}
This is the URL to hit in postman :
localhost:8080/alumnistudents/60aa384ffbf1851f56c71bef
And this is the request body:
{
"firstName": "Babita",
"lastName": "Raman",
"email": "babita#gmail.com",
"alumniDepartment": {
"departmentName": "Android Developer",
"location": "Dubai"
},
"alumniSubjects": [
{
"subjectName": "Java",
"marks": 80
},
{
"subjectName": "Unit testing",
"marks": 60
},
{
"subjectName": "Docker",
"marks": 80
}
]
}
I tried some random code but ended up with
Cannot create a reference to an object with a NULL id.
Can someone help here with how to update the arrays data which is referenced as #DbRef ?
Thanks in advance everyone.

How to generate pojo with Lombok for complex json in Eclipse

Below is the json for pojo creation. I want to create a pojo using Lombok.
I am new to rest assured. How can I create a pojo using Lombok in Eclipse. I want in for nested json, like below Jira API post body request.
{
"fields": {
"project": {
"key": "RA"
},
"summary": "Main order flow broken",
"description": "Creating my fist bug",
"issuetype": {
"name": "Bug"
}
}
}
I have created the below pojo manually, and I am not sure if it's correct. How can I call the generated pojo in post body?
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public class createissue {
private fieldss fields;
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public static class fieldss {
private Project poject;
private Sting summary;
private String description;
private Issuetype issuetypessuetype;
}
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public static class Project {
private Sting key;
}
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public static class Issuetype {
private Sting name;
}
}
The POJO is correct, It had some typos which I have corrected
public class Lombok {
public static #Data class fieldss {
private Project project;
private String summary;
private String description;
private Issuetype issuetype;
}
public static #Data class createissue {
private fieldss fields;
}
public static #Data class Issuetype {
private String name;
}
public static #Data class Project {
private String key;
}
}
and the below is how you can test
public static void main(String[] args) {
// TODO Auto-generated method stub
Issuetype a1 = new Issuetype();
a1.setName("Bug");
Project a2 = new Project();
a2.setKey("RA");
fieldss a3 = new fieldss();
a3.setDescription("Creating my fist bug");
a3.setSummary("Main order flow broken");
a3.setIssuetype(a1);
a3.setProject(a2);
createissue a4 = new createissue();
a4.setFields(a3);
ObjectMapper mapper = new ObjectMapper();
String abc = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(a4);
System.out.println(abc);
}
You should be able to see the below in the console
{
"fields": {
"project": {
"key": "RA"
},
"summary": "Main order flow broken",
"description": "Creating my fist bug",
"issuetype": {
"name": "Bug"
}
}
}

Json object to pojo conversion

I have a json like this:
"subject": {
"category": [
{
"name": "name1"
},
{
"name": "name2"
},
{
"name": "name3"
},
{
"name": "name4"
}
]
}
So it is an object containing a name array. What could be an equivalent Pojo for this?
Should I create a Subject object which has a string list called category?
I tried this:
public class Subject {
#JsonProperty(value = "category")
private List<String> name;
//getter setter ...
}
But I get nested exception: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
Every object should ideally be a class and every array a collection in Java.
It should be:
public class Subject {
private List<Category> category;
//getters and setters
}
class Category{
String name;
//getters and setters
}
yes you are right ..you can implement POJO like you mentioned
class Subject{
List<String> categories;
// getters and setters
}
In this json file you have Subject object containing one Array of objects "category" if you need values from that Subject object you should extract like this
console.log(Subject.category[0].name);
Why don't you just use Gson. Its pretty solid and well tested.
Subject subject = new Gson().fromJson(jsonObject.toString(), Subject.class);
You can also try this if Gson isn't an option here
public class Subject{
private List<Category> category;
//setter/getter(s)
private static class Category{
String name;
}
}
In addition to dev8080 answer I would suggest using jsonschema2pojo service.
If you paste there your source JSON and select Source type: JSON you will have the following output:
---------------com.example.Subject.java---------------
package com.example;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
public class Subject {
#Valid
private List<Category> category = new ArrayList<Category>();
public List<Category> getCategory() {
return category;
}
public void setCategory(List<Category> category) {
this.category = category;
}
}
---------------com.example.Category.java---------------
package com.example;
public class Category {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
And you can easily tweak it using options or adopt some parts by hand.

Categories

Resources