Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Sử dụng @JsonAnyGetter và @JsonAnySetter trong Jackson

Hai annotation này xử lý các trường động/không xác định trước trong JSON – lưu vào Map thay vì field cố định.

Chức năng

  • @JsonAnyGetter: Đánh dấu method getter trả về Map – các entry sẽ được flatten ra thành field JSON khi serialize
  • @JsonAnySetter: Đánh dấu method setter nhận (String key, Object value) – các field JSON không khớp field nào sẽ chuyển vào đây khi deserialize

Ví dụ: Employee với thông tin bổ sung động


import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.*;
import java.io.IOException;
import java.util.*;

public class JsonAnyGetterSetterDemo {
    public static void main(String[] args) throws IOException {
        Employee emp = new Employee();
        emp.setEmpId(101);
        emp.setFirstName("Lan");
        emp.setLastName("Trần");
        emp.addInfo("skill1", "Java");
        emp.addInfo("skill2", "Spring");
        emp.addInfo("cert", "AWS Certified");
        
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(emp);
        System.out.println("=== Serialized ===");
        System.out.println(json);
        
        // Deserialize
        Employee emp2 = mapper.readValue(json, Employee.class);
        System.out.println("\n=== Deserialized ===");
        System.out.println("ID: " + emp2.getEmpId());
        System.out.println("Name: " + emp2.getFirstName() + " " + emp2.getLastName());
        System.out.println("Extra: " + emp2.getAdditionalInfo());
    }
}

class Employee {
    private int empId;
    private String firstName, lastName;
    private Map<String, String> additionalInfo = new HashMap<>();
    
    // Getters/Setters cố định
    public int getEmpId() { return empId; }
    public void setEmpId(int id) { this.empId = id; }
    public String getFirstName() { return firstName; }
    public void setFirstName(String fn) { this.firstName = fn; }
    public String getLastName() { return lastName; }
    public void setLastName(String ln) { this.lastName = ln; }
    
    // Dynamic fields
    @JsonAnyGetter
    public Map<String, String> getAdditionalInfo() { return additionalInfo; }
    
    @JsonAnySetter
    public void addInfo(String key, String value) {
        additionalInfo.put(key, value);
    }
}

Kết quả JSON


{
  "empId" : 101,
  "firstName" : "Lan",
  "lastName" : "Trần",
  "skill1" : "Java",
  "skill2" : "Spring",
  "cert" : "AWS Certified"
}

Khi nào dùng?

  • Schema JSON không cố định (metadata, tags, attributes tùy chỉnh)
  • Tích hợp hệ thống ngoài thêm field mở rộng
  • Phiên bản API mở rộng không breaking change

Lưu ý: Map key nên là String. Value có thể là Object phức tạp (Jackson sẽ serialize đệ quy).