Converting Complex JSON with Nested Objects and Lists into POJO Classes - Notes By ShariqSP
Converting Complex JSON with Nested Objects and Lists into POJO Classes
When dealing with complex JSON structures, it is important to map them into appropriate POJO (Plain Old Java Object) classes for easy deserialization and manipulation in Java. This process involves creating a class hierarchy that reflects the JSON structure. Below, we will explain the steps and provide an example to illustrate how to handle nested objects and lists of different types of objects.
Example JSON Structure
Consider the following JSON:
Diagram: JSON to POJO Conversion
The following diagram visually represents how the complex JSON structure is converted into corresponding POJO classes:
JSON
{ "userId": 1, "username": "shariq", "profile": { ... }, "roles": [ ... ], "settings": { ... } }
User (Root POJO)
+ userId: int + username: String + profile: Profile + roles: List+ settings: Settings
Profile
+ firstName: String + lastName: String + contactInfo: ContactInfo
List<Role>
+ roleId: int + roleName: String
Settings
+ theme: String + notificationsEnabled: boolean
ContactInfo
+ email: String + phoneNumbers: List
This diagram shows the following:
- The JSON root is converted into the
User
class. - The nested objects (
profile
,roles
, andsettings
) map to separate POJO classes. - Nested objects within
Profile
, such asContactInfo
, are further represented by their own POJO. - Lists in JSON, such as
roles
andphoneNumbers
, map toList
fields in Java.
{
"userId": 1,
"username": "shariq",
"profile": {
"firstName": "Shariq",
"lastName": "SP",
"contactInfo": {
"email": "shariq@shariqsp.com",
"phoneNumbers": ["1234567890", "9876543210"]
}
},
"roles": [
{"roleId": 1, "roleName": "Admin"},
{"roleId": 2, "roleName": "Editor"}
],
"settings": {
"theme": "dark",
"notificationsEnabled": true
}
}
Steps to Map JSON to POJO
- Analyze the JSON structure: Identify the nested objects and arrays. For each nested structure, create a corresponding POJO class.
-
Define POJO classes: Use appropriate data types such as
String
,int
,boolean
,List<T>
, or other POJO classes to represent the JSON fields. -
Use Jackson annotations (if needed): Annotations like
@JsonProperty
can be used to map JSON keys to Java field names when they do not match. -
Deserialize JSON to Java objects: Use Jackson's
ObjectMapper
to convert the JSON string into the root POJO class.
POJO Class Definitions
// Root Class
public class User {
private int userId;
private String username;
private Profile profile;
private List<Role> roles;
private Settings settings;
// Getters and setters
}
// Nested Profile Class
public class Profile {
private String firstName;
private String lastName;
private ContactInfo contactInfo;
// Getters and setters
}
// Nested ContactInfo Class
public class ContactInfo {
private String email;
private List<String> phoneNumbers;
// Getters and setters
}
// Role Class (for the roles array)
public class Role {
private int roleId;
private String roleName;
// Getters and setters
}
// Settings Class
public class Settings {
private String theme;
private boolean notificationsEnabled;
// Getters and setters
}
Deserializing JSON to POJOs
To deserialize the JSON into the root User
class, use the following code:
import com.fasterxml.jackson.databind.ObjectMapper;
public class Main {
public static void main(String[] args) {
String json = "{ \"userId\": 1, \"username\": \"shariq\", \"profile\": { ... }, \"roles\": [...], \"settings\": { ... } }"; // Full JSON here
ObjectMapper mapper = new ObjectMapper();
try {
User user = mapper.readValue(json, User.class);
System.out.println(user.getUsername()); // Access deserialized data
} catch (Exception e) {
e.printStackTrace();
}
}
}
Key Points
- Nesting: For every nested object in the JSON, create a corresponding Java class.
-
Lists: Use
List<T>
to represent JSON arrays of objects, whereT
is the type of object in the array. -
Annotations: Use Jackson annotations like
@JsonProperty
for mapping mismatched field names or handling customization. - Error Handling: Ensure proper exception handling during deserialization to handle invalid or unexpected JSON structures.
Final Output
After deserialization, you can access all the nested data using getter methods of the POJO classes. For instance, to access the first phone number:
String firstPhoneNumber = user.getProfile().getContactInfo().getPhoneNumbers().get(0);
System.out.println(firstPhoneNumber); // Output: 1234567890
This approach makes it easy to work with complex JSON data in a structured and type-safe manner.