Of course! Working with JSON strings in Java is a fundamental task. There are several excellent libraries to handle this, but the most modern and recommended approach is using Jakarta JSON Binding (JSON-B) or Jackson.
Here's a comprehensive guide covering the most common scenarios, from simple to complex.
The Modern Standard: Using Jakarta JSON-B (Recommended)
Jakarta JSON-B is a standard API for binding JSON data to Java objects and vice-versa. It's included in Java EE (now Jakarta EE) and is the default in many modern environments like Spring Boot. The most popular implementation is Yasson.
Step 1: Add Dependencies
You need two dependencies: the API and the implementation (Yasson).
Maven (pom.xml):
<dependency>
<groupId>jakarta.json.bind</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<version>3.0.3</version>
</dependency>
Gradle (build.gradle):
implementation 'jakarta.json.bind:jakarta.json-api:3.0.0' implementation 'org.eclipse:yasson:3.0.3'
Step 2: Create a Java Class (POJO)
Your Java class should have fields that match the keys in your JSON string. Use @JsonbProperty to customize the mapping if needed.
import jakarta.json.bind.annotation.JsonbProperty;
import jakarta.json.bind.annotation.JsonbDateFormat;
import java.time.LocalDate;
import java.util.List;
public class User {
// This field will map to the "userName" key in the JSON
@JsonbProperty("userName")
private String name;
private int age;
private boolean isActive;
@JsonbDateFormat("yyyy-MM-dd") // Customize date format
private LocalDate registrationDate;
private List<String> roles;
// Getters and Setters (required for JSON-B)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public boolean isActive() { return isActive; }
public void setActive(boolean active) { isActive = active; }
public LocalDate getRegistrationDate() { return registrationDate; }
public void setRegistrationDate(LocalDate registrationDate) { this.registrationDate = registrationDate; }
public List<String> getRoles() { return roles; }
public void setRoles(List<String> roles) { this.roles = roles; }
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", isActive=" + isActive +
", registrationDate=" + registrationDate +
", roles=" + roles +
'}';
}
}
Step 3: Perform JSON Operations
Create a Jsonb instance to handle the conversion.
import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 1. Create a Jsonb instance
Jsonb jsonb = JsonbBuilder.create();
// --- JSON String to Java Object (Deserialization) ---
String jsonString = """
{
"userName": "John Doe",
"age": 30,
"isActive": true,
"registrationDate": "2025-10-27",
"roles": ["ADMIN", "USER"]
}
""";
User user = jsonb.fromJson(jsonString, User.class);
System.out.println("--- Deserialized Object ---");
System.out.println(user);
System.out.println("Name: " + user.getName());
System.out.println("Role: " + user.getRoles().get(0));
System.out.println();
// --- Java Object to JSON String (Serialization) ---
User newUser = new User();
newUser.setName("Jane Smith");
newUser.setAge(28);
newUser.setActive(true);
newUser.setRegistrationDate(LocalDate.now());
newUser.setRoles(Arrays.asList("MANAGER", "USER"));
String newJsonString = jsonb.toJson(newUser);
System.out.println("--- Serialized JSON String ---");
System.out.println(newJsonString);
}
}
Output:
--- Deserialized Object ---
User{name='John Doe', age=30, isActive=true, registrationDate=2025-10-27, roles=[ADMIN, USER]}
Name: John Doe
Role: ADMIN
--- Serialized JSON String ---
{"isActive":true,"age":28,"name":"Jane Smith","registrationDate":"2025-05-21","roles":["MANAGER","USER"]}
The Most Popular Library: Jackson
Jackson is the de-facto standard in the Java world, especially in the Spring ecosystem. It's extremely powerful and flexible.
Step 1: Add Dependencies
Maven (pom.xml):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
(This single dependency is usually enough, as it includes the core and databind modules).
Step 2: Create a Java Class (POJO)
The class structure is very similar to JSON-B.
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
import java.util.List;
public class User {
// Maps to "userName" in JSON
@JsonProperty("userName")
private String name;
private int age;
private boolean isActive;
// Configures date format
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate registrationDate;
private List<String> roles;
// Getters and Setters
public String getName() { return name; }
public void setName(String name) { this.name = name; }
// ... other getters and setters
}
Step 3: Perform JSON Operations
Jackson uses an ObjectMapper for all conversions.
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// 1. Create an ObjectMapper instance
ObjectMapper objectMapper = new ObjectMapper();
// --- JSON String to Java Object (Deserialization) ---
String jsonString = """
{
"userName": "John Doe",
"age": 30,
"isActive": true,
"registrationDate": "2025-10-27",
"roles": ["ADMIN", "USER"]
}
""";
try {
User user = objectMapper.readValue(jsonString, User.class);
System.out.println("--- Deserialized Object ---");
System.out.println(user);
System.out.println("Name: " + user.getName());
System.out.println();
// --- Java Object to JSON String (Serialization) ---
User newUser = new User();
newUser.setName("Jane Smith");
newUser.setAge(28);
newUser.setActive(true);
newUser.setRegistrationDate(LocalDate.now());
newUser.setRoles(Arrays.asList("MANAGER", "USER"));
// For pretty printing
String newJsonString = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(newUser);
System.out.println("--- Serialized JSON String ---");
System.out.println(newJsonString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
Output:
--- Deserialized Object ---
User{name='John Doe', age=30, isActive=true, registrationDate=2025-10-27, roles=[ADMIN, USER]}
Name: John Doe
--- Serialized JSON String ---
{
"name" : "Jane Smith",
"age" : 28,
"isActive" : true,
"registrationDate" : "2025-05-21",
"roles" : [ "MANAGER", "USER" ]
}
Handling JSON Without a Class (Simple Parsing)
Sometimes you don't have a predefined Java class and just need to read a value from a JSON string. For this, you can use the jakarta.json API (also known as JSON-P), which is a lower-level API for parsing, creating, and manipulating JSON.
Step 1: Add Dependency
This is usually included with JSON-B, but can be standalone.
Maven (pom.xml):
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.1.3</version>
</dependency>
Step 2: Parse the JSON String
import jakarta.json.Json;
import jakarta.json.JsonObject;
import jakarta.json.JsonReader;
import java.io.StringReader;
public class SimpleJsonParser {
public static void main(String[] args) {
String jsonString = """
{
"userName": "John Doe",
"age": 30,
"isActive": true,
"address": {
"street": "123 Main St",
"city": "New York"
}
}
""";
// Use try-with-resources to automatically close the reader
try (JsonReader jsonReader = Json.createReader(new StringReader(jsonString))) {
// The entire JSON is read as a JsonObject
JsonObject jsonObject = jsonReader.readObject();
// Get simple values
String name = jsonObject.getString("userName");
int age = jsonObject.getInt("age");
boolean isActive = jsonObject.getBoolean("isActive");
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Is Active: " + isActive);
// Get a nested JsonObject
JsonObject address = jsonObject.getJsonObject("address");
String city = address.getString("city");
System.out.println("City: " + city);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
Name: John Doe
Age: 30
Is Active: true
City: New York
Summary: Which One to Choose?
| Feature | Jakarta JSON-B | Jackson | jakarta.json (JSON-P) |
|---|---|---|---|
| Primary Use | Binding JSON to POJOs (Object <-> JSON). | Binding JSON to POJOs (Object <-> JSON). Extremely powerful. | Parsing and manipulating JSON documents (tree model). |
| Ease of Use | Very easy, standard API. | Easy, very flexible with annotations. | More verbose, lower-level. |
| Performance | Good. | Excellent, often the fastest. | Good. |
| Best For | Standardized projects, Jakarta EE/Spring Boot apps where you just need simple binding. | The most common choice. Ideal for any project, especially complex ones needing fine-grained control. | When you don't have a POJO, need to modify a JSON document, or only need to read a few values. |
| Recommendation | Great starting point. The modern standard. | The industry standard. Most widely used and supported. | Perfect for simple, one-off parsing tasks. |
