0
0
Lập trình
Admin Team
Admin Teamtechmely

Hướng Dẫn Toàn Diện Về Jackson Với Ví Dụ Cụ Thể

Đăng vào 3 tuần trước

• 6 phút đọc

Chủ đề:

#java#json#jackson

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 Copy
<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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
// 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 Copy
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 Copy
// 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 Copy
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 Copy
// 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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
@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 Copy
// 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 Copy
// 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ớ:

  1. ObjectMapper là lớp trung tâm cho việc đọc/ghi JSON
  2. Sử dụng readValue() để chuyển đổi JSON thành đối tượng Java
  3. Sử dụng writeValueAsString() để chuyển đổi đối tượng Java thành JSON
  4. Tạo các JsonSerializerJsonDeserializer tùy chỉnh cho các kiểu phức tạp
  5. Sử dụng JsonNode cho mô hình cây và xây dựng JSON thủ công
  6. Cấu hình ObjectMapper với nhiều tính năng khác nhau để đáp ứng nhu cầu khác nhau.
Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào