คลาส DeserializationProblemHandler สามารถลงทะเบียนเพื่อถูกเรียกเมื่อพบปัญหาที่อาจ recover ได้ระหว่าง deserialization เราสามารถจัดการ error ระหว่าง deserialize JSON โดย implement เมธอด handleUnknownProperty() ของ DeserializationProblemHandler
Syntax
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p,
JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws IOException
ตัวอย่างการใช้งาน
import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.*;
public class DeserializationErrorTest {
public static void main(String[] args) throws JsonMappingException, JsonGenerationException, IOException {
String jsonString = "{\"id\":\"101\", \"name\":\"Ravi Chandra\", \"address\":\"Pune\", \"salary\":\"40000\"}";
ObjectMapper objectMapper = new ObjectMapper();
DeserializationProblemHandler deserializationProblemHandler = new UnMarshallingErrorHandler();
objectMapper.addHandler(deserializationProblemHandler);
Customer customer = objectMapper.readValue(jsonString, Customer.class);
System.out.println(customer);
}
}
// UnMarshallingErrorHandler class
class UnMarshallingErrorHandler extends DeserializationProblemHandler {
@Override
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser jp,
JsonDeserializer<?> deserializer, Object beanOrClass, String propertyName)
throws IOException, JsonProcessingException {
boolean result = false;
super.handleUnknownProperty(ctxt, jp, deserializer, beanOrClass, propertyName);
System.out.println("Property with name '" + propertyName + "' doesn't exist in Class of type '"
+ beanOrClass.getClass().getName() + "'");
return true; // true = handle error และ continue deserializing
// false = หยุด deserialization ทันที
}
}
// Customer class (ไม่มี salary field)
class Customer {
private int id;
private String name;
private String address;
// getters/setters...
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", address=" + address + "]";
}
}
ผลลัพธ์เมื่อ return true
Property with name 'salary' doesn't exist in Class of type 'Customer'
Customer [id=101, name=Ravi Chandra, address=Pune]
ผลลัพธ์เมื่อ return false
Property with name 'salary' doesn't exist in Class of type 'Customer'
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "salary" (class Customer), not marked as ignorable
(3 known properties: "id", "address", "name")
at [Source: (String)"{"id":"101", "name":"Ravi Chandra", "address":"Pune", "salary":"40000" }"; line: 1, column: 65]
คำอธิบาย
- return true: จัดการ error เอง log/warning แล้ว continue deserialize ฟิลด์อื่นต่อ (lenient)
- return false: หยุดการ deserialize ทันที และโยน exception (strict)
เมธอดอื่นๆ ของ DeserializationProblemHandler
handleWeirdStringValue()- จัดการ string value ที่แปลกประหลาดhandleWeirdNumberValue()- จัดการ number value ที่แปลกประหลาดhandleWeirdKey()- จัดการ key ที่แปลกประหลาดhandleMissingInstantiator()- จัดการไม่มี constructor/creatorhandleInstantiationProblem()- จัดการปัญหา instantiation
การตั้งค่าระดับ Global (Alternative)
แทนที่จะใช้ handler สามารถตั้งค่า global ได้:
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
สรุป
DeserializationProblemHandler ให้การจัดการ deserialization errors แบบ fine-grained และ customizable เหมาะสำหรับกรณีที่ต้องการ logging, monitoring, หรือ conditional handling ตาม property name หรือ type