JSON (JavaScript Object Notation) has become the de facto standard for data exchange in modern applications. Whether you're working with APIs, microservices, cloud platforms, or configuration files, JSON provides a human-readable, lightweight, and structured way to store and transfer data.
In Java, handling JSON is essential. While the standard library provides basic I/O tools, popular libraries like Jackson and Gson make working with JSON files much easier. This tutorial explores reading, writing, parsing, and serializing JSON data in Java with practical examples and best practices.
Basics of Java I/O
Streams, Readers, Writers
- InputStream/OutputStream → Binary data (images, PDFs).
- Reader/Writer → Character data (JSON, XML, CSV).
- JSON is character-based, so we typically use
Reader
/Writer
or modern NIO.2 APIs.
Reading and Writing JSON Files with Jackson
Dependency
Add Jackson to your Maven pom.xml
:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version>
</dependency>
Define a POJO
public class User {
private String name;
private int age;
private String country;
// Getters and Setters
}
Writing JSON to File
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
public class JacksonWriteExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
User user = new User();
user.setName("Alice");
user.setAge(30);
user.setCountry("USA");
mapper.writeValue(new File("user.json"), user);
System.out.println("JSON written successfully.");
}
}
Reading JSON from File
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
public class JacksonReadExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(new File("user.json"), User.class);
System.out.println(user.getName() + " - " + user.getCountry());
}
}
Reading and Writing JSON Files with Gson
Dependency
Add Gson to your Maven pom.xml
:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
Writing JSON with Gson
import com.google.gson.Gson;
import java.io.FileWriter;
public class GsonWriteExample {
public static void main(String[] args) throws Exception {
Gson gson = new Gson();
User user = new User();
user.setName("Bob");
user.setAge(25);
user.setCountry("UK");
try (FileWriter writer = new FileWriter("user.json")) {
gson.toJson(user, writer);
}
System.out.println("JSON written using Gson.");
}
}
Reading JSON with Gson
import com.google.gson.Gson;
import java.io.FileReader;
public class GsonReadExample {
public static void main(String[] args) throws Exception {
Gson gson = new Gson();
try (FileReader reader = new FileReader("user.json")) {
User user = gson.fromJson(reader, User.class);
System.out.println(user.getName() + " - " + user.getAge());
}
}
}
Intermediate Concepts
Serialization & Deserialization
- Serialization: Java object → JSON string/file.
- Deserialization: JSON string/file → Java object.
Collections & Nested Objects
Both Jackson and Gson support lists and nested objects:
List<User> users = Arrays.asList(new User("Alice", 30, "USA"), new User("Bob", 25, "UK"));
mapper.writeValue(new File("users.json"), users);
Buffered I/O
For large JSON files, wrap Readers/Writers with BufferedReader/BufferedWriter for better performance.
Streaming API
- Jackson →
JsonParser
andJsonGenerator
for streaming large JSON files. - Gson →
JsonReader
for streaming.
Advanced I/O with NIO and NIO.2
Using Files API
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
public class NioJsonExample {
public static void main(String[] args) throws Exception {
Path path = Paths.get("config.json");
// Write string
Files.writeString(path, "{ "app": "demo", "version": 1 }", StandardCharsets.UTF_8);
// Read string
String json = Files.readString(path, StandardCharsets.UTF_8);
System.out.println(json);
}
}
FileChannel and Memory-Mapped Files
For very large JSON files, use FileChannel
with MappedByteBuffer
for efficient access.
WatchService
Monitor JSON configuration files and reload automatically.
Performance & Best Practices
- Use Jackson for enterprise projects (faster, richer features).
- Use Gson for smaller apps or simple JSON tasks.
- Always close I/O resources using try-with-resources.
- Handle character encoding explicitly (
UTF-8
). - For very large files, prefer streaming APIs.
- Validate JSON input to avoid parsing errors.
Framework Case Studies
- Spring Boot: Uses Jackson by default for JSON serialization in REST APIs.
- Hibernate: Integrates JSON for storing structured fields.
- Logging Frameworks: JSON log appenders.
- Netty: Uses JSON for protocol data exchange.
- Microservices: JSON as the primary communication format.
Real-World Scenarios
- API Clients: Parse REST API responses in JSON.
- Configuration Management: Store app configs in JSON.
- Database Export/Import: Exchange structured data in JSON.
- Log Processing: JSON-based structured logging.
- Data Pipelines: JSON as the staging format.
📌 What's New in Java Versions?
- Java 7+: NIO.2
Path
,Files
,WatchService
. - Java 8: Streams API works well with JSON collections.
- Java 11:
Files.readString
,Files.writeString
for JSON handling. - Java 17: NIO optimizations improve JSON processing.
- Java 21: Virtual threads simplify blocking I/O with JSON.
Conclusion & Key Takeaways
JSON handling is essential in modern Java applications, from microservices to cloud-native apps. Libraries like Jackson and Gson make it straightforward to read, write, and parse JSON files. Combining them with NIO.2 APIs ensures scalability and efficiency.
Key Takeaways:
- Use Jackson for robust, enterprise-grade JSON handling.
- Use Gson for lightweight tasks.
- Combine with NIO.2 for modern file I/O.
- Always specify encoding and validate JSON inputs.
FAQ
Q1. Which is faster: Jackson or Gson?
A: Jackson is generally faster and feature-rich; Gson is simpler.
Q2. Can I use Java’s default libraries for JSON?
A: Java SE doesn’t provide built-in JSON parsing; external libraries are needed.
Q3. How do I handle large JSON files?
A: Use Jackson Streaming API (JsonParser
) or Gson JsonReader
.
Q4. Can I pretty-print JSON?
A: Yes, both Jackson and Gson support pretty-printing.
Q5. How do I read nested JSON objects?
A: Define nested POJOs or use JsonNode
(Jackson) / JsonObject
(Gson).
Q6. Is JSON thread-safe in Jackson/Gson?
A: ObjectMapper
(Jackson) is thread-safe after configuration; Gson is thread-safe.
Q7. Can I serialize null values?
A: Yes, but you can configure libraries to ignore them.
Q8. Can I use Streams API with JSON?
A: Yes, convert JSON collections to Streams for processing.
Q9. How do frameworks like Spring Boot use JSON?
A: Spring Boot uses Jackson by default for REST APIs.
Q10. What’s the analogy for JSON handling in Java?
A: Think of Jackson as a Swiss Army knife for JSON, while Gson is a pocket knife — simpler but handy.