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

Triển khai custom deserializer với @JsonDeserialize trong Jackson (Java)

Annotation @JsonDeserialize khai báo custom deserializer khi chuyển JSON → Java object. Implement bằng cách extends StdDeserializer<T> và override deserialize().

Cú pháp

@Target({ANNOTATION_TYPE, METHOD, FIELD, TYPE, PARAMETER})
@Retention(RUNTIME)
public @interface JsonDeserialize {
    Class<? extends JsonDeserializer<?>> using() default JsonDeserializer.None.class;
}

Ví dụ hoàn chỉnh

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.*;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

public class JsonDeserializeTest {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        
        // Serialize
        Employee emp = new Employee(115, "Adithya");
        String json = mapper.writeValueAsString(emp);
        System.out.println("Serialized: " + json);
        
        // Deserialize với custom deserializer
        emp = mapper.readValue(json, Employee.class);
        System.out.println("Deserialized: " + emp);
    }
}

// Custom Deserializer
class CustomDeserializer extends StdDeserializer<Employee> {
    public CustomDeserializer() { this(Employee.class); }
    public CustomDeserializer(Class<Employee> t) { super(t); }
    
    @Override
    public Employee deserialize(JsonParser jp, DeserializationContext ctx) 
            throws IOException, JsonProcessingException {
        
        JsonNode node = jp.getCodec().readTree(jp); // Đọc toàn bộ tree
        int id = node.get("id").asInt();
        String name = node.get("name").asText();
        return new Employee(id, name);
    }
}

// Entity với @JsonDeserialize
@JsonDeserialize(using = CustomDeserializer.class)
class Employee {
    private int id;
    private String name;
    
    public Employee(int id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public int getId() { return id; }
    public String getName() { return name; }
    
    @Override
    public String toString() {
        return "ID: " + id + "\nName: " + name;
    }
}

Output

Serialized: {"id":115,"name":"Adithya"}
Deserialized: ID: 115
Name: Adithya

Các trường hợp dùng custom deserializer

  • JSON format không khớp với Java object (tên field khác, nested structure khác).
  • Cần validation, transformation, computed field khi deserialize.
  • Polymorphic deserialization (dựa trên field type discriminant).
  • Xử lý date format non-standard, nullable fields đặc biệt.

Best Practice (Jackson 2.12+)

  • Dùng JsonNode hoặc ObjectCodec.readTree() thay vì parse token thủ công (code gọn, ít bug).
  • Đăng ký deserializer qua SimpleModule cho global config thay vì annotate từng class.
  • Kết hợp @JsonCreator cho constructor/factory method đơn giản hơn.