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
JsonNodehoặcObjectCodec.readTree()thay vì parse token thủ công (code gọn, ít bug). - Đăng ký deserializer qua
SimpleModulecho global config thay vì annotate từng class. - Kết hợp
@JsonCreatorcho constructor/factory method đơn giản hơn.