Giới Thiệu Về Jackson
Jackson là một thư viện xử lý JSON hiệu suất cao cho Java, được sử dụng rộng rãi trong các ứng dụng cần xử lý dữ liệu JSON. Jackson cho phép:
- Chuyển đổi đối tượng Java thành JSON
- Chuyển đổi JSON thành đối tượng Java
- Xử lý và thao tác dữ liệu JSON (đọc, ghi, duyệt)
- Liên kết dữ liệu giữa JSON và đối tượng Java
Thư viện này thường được sử dụng trong Spring Framework và các dịch vụ web RESTful.
Cách Thêm Jackson Vào Dự Án
Maven (pom.xml)
xml
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.15.2</version>
</dependency>
</dependencies>
Gradle (build.gradle)
groovy
dependencies {
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2'
}
ObjectMapper và Cách Tạo
ObjectMapper là lớp chính trong Jackson cung cấp chức năng đọc và ghi JSON.
Tạo ObjectMapper Từ Constructor Rỗng
java
import com.fasterxml.jackson.databind.ObjectMapper;
// Cách đơn giản nhất để tạo ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Tạo ObjectMapper Từ File
java
import java.io.File;
import com.fasterxml.jackson.databind.ObjectMapper;
// Tạo ObjectMapper và đọc JSON từ file
ObjectMapper mapper = new ObjectMapper();
File jsonFile = new File("data.json");
MyObject obj = mapper.readValue(jsonFile, MyObject.class);
Tạo ObjectMapper Từ InputStream
java
import java.io.InputStream;
import com.fasterxml.jackson.databind.ObjectMapper;
// Tạo ObjectMapper và đọc JSON từ InputStream
ObjectMapper mapper = new ObjectMapper();
try (InputStream inputStream = getClass().getResourceAsStream("/data.json")) {
MyObject obj = mapper.readValue(inputStream, MyObject.class);
}
Các Phương Thức Quan Trọng Của ObjectMapper
readValue() - Chuyển Đổi JSON Thành Đối Tượng Java
java
// Từ String
String jsonString = "{\"name\":\"John\", \"age\":30}";
Person person = mapper.readValue(jsonString, Person.class);
// Từ File
Person person = mapper.readValue(new File("person.json"), Person.class);
// Từ URL
Person person = mapper.readValue(new URL("http://example.com/person.json"), Person.class);
writeValueAsString() - Chuyển Đối Tượng Java Thành Chuỗi JSON
java
Person person = new Person("John", 30);
String jsonString = mapper.writeValueAsString(person);
System.out.println(jsonString); // Output: {"name":"John","age":30}
convertValue() - Chuyển Đổi Giữa Các Kiểu
java
// Chuyển đổi từ kiểu này sang kiểu khác (hữu ích cho việc chuyển đổi Map sang Object)
Map<String, Object> map = new HashMap<>();
map.put("name", "John");
map.put("age", 30);
Person person = mapper.convertValue(map, Person.class);
readTree() - Phân Tích JSON Thành Mô Hình Cây
java
String jsonString = "{\"name\":\"John\", \"age\":30, \"hobbies\":[\"reading\", \"swimming\"]}";
JsonNode rootNode = mapper.readTree(jsonString);
// Truy cập các giá trị
String name = rootNode.get("name").asText(); // "John"
int age = rootNode.get("age").asInt(); // 30
JsonNode hobbies = rootNode.get("hobbies"); // Node mảng
Các Phương Thức Quan Trọng Khác
java
// Ghi JSON vào file
mapper.writeValue(new File("output.json"), person);
// In JSON đẹp
String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
// Cấu hình ObjectMapper
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
JsonSerializer và JsonDeserializer
Ví Dụ Về JsonSerializer Tùy Chỉnh
java
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
* Bộ tuần tự hóa tùy chỉnh cho các đối tượng LocalDate để định dạng chúng thành "yyyy-MM-dd"
*/
public class LocalDateSerializer extends JsonSerializer<LocalDate> {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeString(value.format(formatter));
}
}
Ví Dụ Về JsonDeserializer Tùy Chỉnh
java
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
/**
* Bộ giải tuần tự hóa tùy chỉnh để chuyển đổi chuỗi "yyyy-MM-dd" thành LocalDate
*/
public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt)
throws IOException {
String dateStr = p.getText();
return LocalDate.parse(dateStr, formatter);
}
}
Sử Dụng Bộ Tuần Tự Hóa/Bộ Giải Tùy Chỉnh Trong Một Lớp
java
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.time.LocalDate;
public class Person {
private String name;
private int age;
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate birthDate;
// Các hàm khởi tạo, getter và setter
public Person() {}
public Person(String name, int age, LocalDate birthDate) {
this.name = name;
this.age = age;
this.birthDate = birthDate;
}
// Getter và setter
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 LocalDate getBirthDate() { return birthDate; }
public void setBirthDate(LocalDate birthDate) { this.birthDate = birthDate; }
}
Chuyển Đổi Đối Tượng Java Thành JSON Và Ngược Lại
Đối Tượng Java Thành JSON
java
ObjectMapper mapper = new ObjectMapper();
// Tạo một đối tượng Person
Person person = new Person("Alice", 25, LocalDate.of(1998, 5, 15));
// Chuyển đổi thành chuỗi JSON
String jsonString = mapper.writeValueAsString(person);
System.out.println(jsonString);
// Output: {"name":"Alice","age":25,"birthDate":"1998-05-15"}
// Chuyển đổi thành file JSON
mapper.writeValue(new File("person.json"), person);
JSON Thành Đối Tượng Java
java
ObjectMapper mapper = new ObjectMapper();
// Từ chuỗi JSON
String jsonString = "{\"name\":\"Bob\",\"age\":30,\"birthDate\":\"1993-02-10\"}";
Person person = mapper.readValue(jsonString, Person.class);
// Từ file JSON
Person personFromFile = mapper.readValue(new File("person.json"), Person.class);
// Từ URL
Person personFromUrl = mapper.readValue(
new URL("http://example.com/api/person/123"), Person.class);
Xây Dựng JSON Thủ Công Với JsonNode
Sử Dụng mapper.createObjectNode() và mapper.createArrayNode()
java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
ObjectMapper mapper = new ObjectMapper();
// Tạo một node đối tượng rỗng
ObjectNode personNode = mapper.createObjectNode();
// Thêm thuộc tính vào đối tượng
personNode.put("name", "John");
personNode.put("age", 30);
personNode.put("isStudent", false);
// Tạo một node mảng
ArrayNode hobbiesNode = mapper.createArrayNode();
hobbiesNode.add("Reading");
hobbiesNode.add("Swimming");
hobbiesNode.add("Coding");
// Thêm mảng vào đối tượng
personNode.set("hobbies", hobbiesNode);
// Tạo một đối tượng lồng nhau
ObjectNode addressNode = mapper.createObjectNode();
addressNode.put("street", "123 Main St");
addressNode.put("city", "New York");
addressNode.put("zipCode", "10001");
personNode.set("address", addressNode);
// Chuyển đổi thành chuỗi JSON
String jsonString = mapper.writeValueAsString(personNode);
System.out.println(jsonString);
/* Output:
{
"name": "John",
"age": 30,
"isStudent": false,
"hobbies": ["Reading", "Swimming", "Coding"],
"address": {
"street": "123 Main St",
"city": "New York",
"zipCode": "10001"
}
}
*/
// Chuyển JsonNode trở lại thành đối tượng Java
Person person = mapper.treeToValue(personNode, Person.class);
Các Chủ Đề Quan Trọng Khác
Xử Lý Ngày Và Thời Gian
java
ObjectMapper mapper = new ObjectMapper();
// Cấu hình định dạng ngày
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// Đối với Java 8 Date/Time API, đăng ký module JSR310
// Thêm dependency: com.fasterxml.jackson.datatype:jackson-datatype-jsr310
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
Xử Lý Các Kiểu Đối Tượng Đa Hình
java
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
private String name;
// getter và setter
}
public class Dog extends Animal {
private String breed;
// getter và setter
}
public class Cat extends Animal {
private boolean likesCream;
// getter và setter
}
Bỏ Qua Các Thuộc Tính
java
// Bỏ qua các thuộc tính trong quá trình tuần tự hóa
@JsonIgnoreProperties({"internalId", "secretKey"})
public class User {
private String name;
private String email;
@JsonIgnore // Bỏ qua thuộc tính riêng lẻ
private String password;
// getter và setter
}
Xử Lý Các Giá Trị Null
java
// Cấu hình cách xử lý các giá trị null
mapper.setSerializationInclusion(Include.NON_NULL); // Bỏ qua các trường null
mapper.setSerializationInclusion(Include.NON_EMPTY); // Bỏ qua các collection và chuỗi rỗng
// Hoặc sử dụng annotation trên các trường cụ thể
public class Product {
@JsonInclude(Include.NON_NULL)
private String description;
// getter và setter
}
Kết Luận
Jackson là một thư viện mạnh mẽ và linh hoạt cho xử lý JSON trong Java. Những điểm chính cần nhớ:
- ObjectMapper là lớp trung tâm cho việc đọc/ghi JSON
- Sử dụng readValue() để chuyển đổi JSON thành đối tượng Java
- Sử dụng writeValueAsString() để chuyển đổi đối tượng Java thành JSON
- Tạo các JsonSerializer và JsonDeserializer tùy chỉnh cho các kiểu phức tạp
- Sử dụng JsonNode cho mô hình cây và xây dựng JSON thủ công
- Cấu hình ObjectMapper với nhiều tính năng khác nhau để đáp ứng nhu cầu khác nhau.