Of course! Handling JSON responses in Java is a fundamental task for modern web development, especially when interacting with REST APIs. Here’s a comprehensive guide covering the most popular methods, from the basic to the most modern.

We'll cover three main approaches:
- Manual Parsing with
org.json: Simple, no dependencies, but tedious for complex objects. - Jackson (The De Facto Standard): The most popular, powerful, and flexible library.
- Gson (Google's Library): Very similar to Jackson, also extremely popular and easy to use.
The Scenario
Let's assume we've received the following JSON response from an API:
{
"userId": 1,
"id": 101,: "Learn how to handle JSON in Java",
"completed": false
}
Our goal is to convert this JSON string into a Java object (a process called deserialization).
Manual Parsing with org.json (The Standard Library)
This approach uses the org.json library, which is included by default in many environments (like Android) or can be added as a dependency. It's great for simple, one-off tasks but becomes very verbose for complex JSON.

Step 1: Add Dependency (if not already present)
If you're using Maven, add this to your pom.xml:
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20251013</version>
</dependency>
Step 2: Create a Java Class (POJO)
It's good practice to have a class that mirrors the JSON structure. However, with org.json, you often work directly with the JSONObject and JSONArray classes.
// You can still create a POJO for type safety
public class Todo {
private int userId;
private int id;
private String title;
private boolean completed;
// Getters and Setters (Crucial for Jackson/Gson, good practice here)
public int getUserId() { return userId; }
public void setUserId(int userId) { this.userId = userId; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public boolean isCompleted() { return completed; }
public void setCompleted(boolean completed) { this.completed = completed; }
@Override
public String toString() {
return "Todo{" +
"userId=" + userId +
", id=" + id +
", title='" + title + '\'' +
", completed=" + completed +
'}';
}
}
Step 3: Parse the JSON String
import org.json.JSONObject;
public class JsonOrgExample {
public static void main(String[] args) {
String jsonResponse = """
{
"userId": 1,
"id": 101,
"title": "Learn how to handle JSON in Java",
"completed": false
}
""";
// Create a JSONObject from the string
JSONObject jsonObject = new JSONObject(jsonResponse);
// Extract values by key and cast them to the appropriate Java type
int userId = jsonObject.getInt("userId");
int id = jsonObject.getInt("id");
String title = jsonObject.getString("title");
boolean completed = jsonObject.getBoolean("completed");
// You can now use these variables
System.out.println("Title: " + title);
System.out.println("Is Completed? " + completed);
// To map to our Todo POJO, you have to do it manually
Todo todo = new Todo();
todo.setUserId(userId);
todo.setId(id);
todo.setTitle(title);
todo.setCompleted(completed);
System.out.println("\nMapped to POJO: " + todo);
}
}
Pros:
- No external dependencies needed in some environments.
- Simple for very basic JSON.
Cons:
- Extremely verbose and error-prone for large or nested JSON.
- You have to manually cast types (
getInt,getString, etc.), which can throw exceptions if the type is wrong. - Tedious mapping to a POJO.
Jackson (The Most Popular & Recommended)
Jackson is the de facto standard for JSON processing in the Java ecosystem. It's incredibly fast, feature-rich, and integrates seamlessly with frameworks like Spring Boot.
Step 1: Add Dependency
Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version> <!-- Use the latest version -->
</dependency>
Step 2: Create a POJO (Plain Old Java Object)
This is where Jackson shines. The JSON keys must match the field names in your Java class (or you can use annotations to map them). The class must have a no-argument constructor.
// This class is identical to the one before
public class Todo {
private int userId;
private int id;
private String title;
private boolean completed;
// Jackson requires a no-arg constructor
public Todo() {
}
// Getters and Setters are MANDATORY
public int getUserId() { return userId; }
public void setUserId(int userId) { this.userId = userId; }
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public boolean isCompleted() { return completed; }
public void setCompleted(boolean completed) { this.completed = completed; }
@Override
public String toString() {
return "Todo{" +
"userId=" + userId +
", id=" + id +
", title='" + title + '\'' +
", completed=" + completed +
'}';
}
}
Step 3: Parse the JSON String
Jackson uses an ObjectMapper to perform the conversion.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonExample {
public static void main(String[] args) {
String jsonResponse = """
{
"userId": 1,
"id": 101,
"title": "Learn how to handle JSON in Java",
"completed": false
}
""";
// 1. Create an instance of ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
try {
// 2. Use the readValue method to map JSON string to a Todo object
// The first argument is the JSON string
// The second argument is the target Java class
Todo todo = objectMapper.readValue(jsonResponse, Todo.class);
// 3. Now you have a fully populated Java object!
System.out.println(todo);
System.out.println("Just the title: " + todo.getTitle());
} catch (JsonProcessingException e) {
System.err.println("Failed to parse JSON: " + e.getMessage());
e.printStackTrace();
}
}
}
That's it! Jackson automatically maps the JSON keys to the POJO fields and handles type conversion.
Common Jackson Annotations
You can use annotations to give Jackson more instructions:
@JsonProperty("json_key"): Maps a JSON key to a different Java field name.@JsonProperty("user_id") private int userId;@JsonIgnore: Excludes a field from serialization/deserialization.@JsonIgnore private String internalNotes;
@JsonFormat: Specifies the format for a date/time field.@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss") private Date createdAt;
Gson (Google's Library)
Gson is another excellent library from Google. Its API is very similar to Jackson's, making it easy to switch between them.
Step 1: Add Dependency
Maven:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version> <!-- Use the latest version -->
</dependency>
Step 2: Create a POJO
The POJO is exactly the same as for Jackson.
public class Todo {
// ... same class as before ...
}
Step 3: Parse the JSON String
Gson uses its own Gson class for conversions.
import com.google.gson.Gson;
public class GsonExample {
public static void main(String[] args) {
String jsonResponse = """
{
"userId": 1,
"id": 101,
"title": "Learn how to handle JSON in Java",
"completed": false
}
""";
// 1. Create an instance of Gson
Gson gson = new Gson();
// 2. Use the fromJson method to map JSON string to a Todo object
// The first argument is the JSON string
// The second argument is the target Java class
Todo todo = gson.fromJson(jsonResponse, Todo.class);
// 3. You have your Java object!
System.out.println(todo);
System.out.println("Just the title: " + todo.getTitle());
}
}
As you can see, the code is almost identical to the Jackson example.
Comparison & Recommendation
| Feature | org.json (Manual) |
Jackson | Gson |
|---|---|---|---|
| Ease of Use | Low (Verbose) | High (Very clean API) | High (Very clean API) |
| Performance | Good | Excellent (Fastest) | Excellent |
| Features | Basic | Extremely Rich (Streaming, Trees, etc.) | Very Rich |
| Dependencies | Often none | One (jackson-databind) |
One (gson) |
| POJO Mapping | Manual (Tedious) | Automatic (with annotations) | Automatic |
| Ecosystem | N/A | Industry Standard, deeply integrated | Very popular, especially in Android |
Final Recommendation
- For any new project, especially a web service or application using a framework like Spring Boot, use Jackson. It's the most robust, performant, and widely-adopted solution.
- If you are working on an Android project, Gson is a great choice and has been the traditional favorite.
- Only use the manual
org.jsonapproach for very simple scripts or if you are in a severely restricted environment where you cannot add external dependencies.
