POJO stands for Plain Old Java Object. It is a simple Java class with fields, getters, setters, and constructors. In your framework, POJOs map directly to JSON request and response bodies. Instead of building JSON strings manually, you create a Java object and let Jackson serialize it. Instead of parsing JSON manually, you let Jackson deserialize it into a Java object.
package com.company.api.pojo.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonInclude;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CreateUserRequest {
private String name;
private String email;
private String phone;
@JsonProperty("job_title")
private String jobTitle;
// No-arg constructor — required by Jackson
public CreateUserRequest() {}
// All-arg constructor — convenient for tests
public CreateUserRequest(String name, String email,
String phone, String jobTitle) {
this.name = name;
this.email = email;
this.phone = phone;
this.jobTitle = jobTitle;
}
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
public String getPhone() { return phone; }
public void setPhone(String phone) { this.phone = phone; }
public String getJobTitle() { return jobTitle; }
public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; }
}package com.company.api.pojo.response;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserResponse {
private int id;
private String name;
private String email;
private String phone;
@JsonProperty("job_title")
private String jobTitle;
@JsonProperty("created_at")
private String createdAt;
// No-arg constructor
public UserResponse() {}
// Getters
public int getId() { return id; }
public String getName() { return name; }
public String getEmail() { return email; }
public String getPhone() { return phone; }
public String getJobTitle() { return jobTitle; }
public String getCreatedAt() { return createdAt; }
// Setters
public void setId(int id) { this.id = id; }
public void setName(String name) { this.name = name; }
public void setEmail(String email) { this.email = email; }
public void setPhone(String phone) { this.phone = phone; }
public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; }
public void setCreatedAt(String createdAt) { this.createdAt = createdAt; }
@Override
public String toString() {
return "UserResponse{id=" + id + ", name='" + name + "', email='" + email + "'}";
}
}| Annotation | Where | Purpose |
|---|---|---|
| @JsonProperty("job_title") | Field | Maps Java camelCase to JSON snake_case |
| @JsonInclude(NON_NULL) | Class | Skips null fields during serialization. Useful for optional request fields. |
| @JsonIgnoreProperties(ignoreUnknown = true) | Class | Ignores extra JSON fields not in the POJO. Prevents deserialization errors. |
| No-arg constructor | Class | Required by Jackson for deserialization. Always add it. |
// Creating a request body — clean and type-safe
CreateUserRequest request = new CreateUserRequest(
"Rahul Sharma",
"rahul@example.com",
"9876543210",
"QA Engineer"
);
// REST Assured serializes it to JSON automatically
Response response = given()
.spec(requestSpec)
.body(request) // Jackson converts POJO to JSON
.when()
.post("/users");
// Deserializing the response — type-safe access
UserResponse user = response.as(UserResponse.class);
System.out.println(user.getName()); // "Rahul Sharma"
System.out.println(user.getId()); // 42
System.out.println(user.getCreatedAt()); // "2024-03-15T10:30:00Z"Always add @JsonIgnoreProperties(ignoreUnknown = true) on response POJOs. APIs evolve — new fields get added. Without this annotation, Jackson throws an exception when it sees a field your POJO does not have. Your tests fail for the wrong reason.
Separate request and response POJOs even if they look similar. A CreateUserRequest has name, email, phone. A UserResponse has those PLUS id, createdAt, updatedAt. Mixing them into one class leads to confusion about which fields are for sending and which are for receiving.
Q: Why do you use POJO classes instead of building JSON strings in your framework?
A: POJOs give us compile-time type safety — if I misspell a field name, the compiler catches it immediately. The IDE provides autocomplete for all fields. Jackson handles serialization and deserialization automatically — I create a Java object and REST Assured converts it to JSON for the request body. For responses, I deserialize into a POJO and access fields with getters instead of parsing JSON paths. We use @JsonProperty for field name mapping between Java camelCase and JSON snake_case, @JsonInclude to skip null fields in requests, and @JsonIgnoreProperties on responses to handle API evolution gracefully.
Key Point: POJOs replace raw JSON strings with type-safe Java objects. Use @JsonProperty for name mapping, @JsonInclude(NON_NULL) on requests, and @JsonIgnoreProperties(ignoreUnknown=true) on responses.