Polymorphic Deserialization হলো সেই প্রক্রিয়া, যেখানে একটি সাধারণ প্যারেন্ট ক্লাস বা ইন্টারফেসের ইনস্ট্যান্সকে JSON ডেটা থেকে সঠিক সাবক্লাসের ইনস্ট্যান্সে রূপান্তর করা হয়। Jackson-এ polymorphic deserialization সহজভাবে @JsonTypeInfo এবং @JsonSubTypes অ্যানোটেশন ব্যবহার করে করা যায়।
এটি subtype এর উপর ভিত্তি করে parent class-এর deserialization প্রক্রিয়া নিয়ন্ত্রণ করতে সাহায্য করে। এটি কার্যকর যখন আপনার অনেক ধরনের অবজেক্ট থাকে, কিন্তু আপনি তাদের একে অপরের সাবক্লাস হিসেবে কাজ করাতে চান।
Jackson-এ Polymorphic Deserialization করতে @JsonTypeInfo এবং @JsonSubTypes ব্যবহার
@JsonTypeInfo
@JsonTypeInfoJackson-কে বলে যে ফিল্ডটি polymorphic deserialization সমর্থন করবে। এটি সাধারণত parent ক্লাসে ব্যবহার করা হয়।
@JsonSubTypes
@JsonSubTypesহল সেই অ্যানোটেশন, যা Jackson-কে জানায় কোন সাবক্লাসগুলো parent ক্লাসের সাথে সম্পর্কিত।
Polymorphic Deserialization Example
ধরা যাক, আমাদের কাছে একটি Shape নামক প্যারেন্ট ক্লাস এবং তার দুইটি সাবক্লাস Circle এবং Rectangle রয়েছে। আমরা JSON থেকে এই ক্লাসগুলোর উপযুক্ত ইনস্ট্যান্স তৈরি করতে চাই।
Step 1: Create Polymorphic Classes
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Circle.class, name = "circle"),
@JsonSubTypes.Type(value = Rectangle.class, name = "rectangle")
})
public abstract class Shape {
private String color;
// Getters and Setters
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public abstract double area(); // Abstract method for calculating area
}
public class Circle extends Shape {
private double radius;
// Constructor, Getters, and Setters
public Circle() {}
public Circle(double radius, String color) {
this.radius = radius;
setColor(color);
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
public class Rectangle extends Shape {
private double length;
private double width;
// Constructor, Getters, and Setters
public Rectangle() {}
public Rectangle(double length, double width, String color) {
this.length = length;
this.width = width;
setColor(color);
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public double area() {
return length * width;
}
}
Step 2: Serialize and Deserialize Polymorphic JSON
import com.fasterxml.jackson.databind.ObjectMapper;
public class PolymorphicDeserializationExample {
public static void main(String[] args) throws Exception {
// JSON representing a Circle
String jsonCircle = "{\"type\":\"circle\",\"color\":\"red\",\"radius\":5.0}";
// JSON representing a Rectangle
String jsonRectangle = "{\"type\":\"rectangle\",\"color\":\"blue\",\"length\":4.0,\"width\":6.0}";
ObjectMapper objectMapper = new ObjectMapper();
// Deserialize the JSON into the appropriate Shape object
Shape shape1 = objectMapper.readValue(jsonCircle, Shape.class);
Shape shape2 = objectMapper.readValue(jsonRectangle, Shape.class);
// Display the deserialized objects
System.out.println("Shape 1: " + shape1.getClass().getSimpleName() + " with area: " + shape1.area());
System.out.println("Shape 2: " + shape2.getClass().getSimpleName() + " with area: " + shape2.area());
}
}
Explanation:
@JsonTypeInfo: এর মাধ্যমে Jackson প্যারেন্ট ক্লাসের টোকেন হিসেবে"type"প্রপার্টি ব্যবহার করবে, যা polymorphic deserialization-এর জন্য কাজ করবে। এই টোকেনের মান"circle"বা"rectangle"হবে।@JsonSubTypes: এখানে,@JsonSubTypesদিয়ে আমরা প্যারেন্ট ক্লাসShapeএর সাবক্লাস হিসেবেCircleএবংRectangleক্লাসের রেফারেন্স তৈরি করেছি।
JSON Input:
- Circle JSON:
{
"type": "circle",
"color": "red",
"radius": 5.0
}
- Rectangle JSON:
{
"type": "rectangle",
"color": "blue",
"length": 4.0,
"width": 6.0
}
JSON Output:
Shape 1: Circle with area: 78.53981633974483
Shape 2: Rectangle with area: 24.0
Important Notes:
@JsonTypeInfo:use = JsonTypeInfo.Id.NAME→ এটি নির্দেশ করে যে টোকেন হিসেবে একটি নাম (এখানেtype) ব্যবহার করা হবে।include = JsonTypeInfo.As.PROPERTY→ এটি JSON-এ টোকেনটি একটি প্রপার্টি হিসেবে ইনক্লুড করবে।property = "type"→ টোকেনের নাম যা JSON এ থাকবে।
@JsonSubTypes:- এটি টোকেনের মানের ভিত্তিতে উপযুক্ত ক্লাসের ইনস্ট্যান্স নির্বাচন করে।
value = Circle.classএবংvalue = Rectangle.class→ এটি সঠিক সাবক্লাস নির্বাচন করতে সাহায্য করে।
Alternative Approach: Using @JsonCreator for Factory Methods
Jackson এর @JsonCreator অ্যানোটেশন ব্যবহার করে আপনি কাস্টম ফ্যাক্টরি মেথডের মাধ্যমে polymorphic deserialization করতে পারেন।
Example with @JsonCreator:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class ShapeFactory {
@JsonCreator
public static Shape createShape(@JsonProperty("type") String type, @JsonProperty("color") String color,
@JsonProperty("radius") double radius, @JsonProperty("length") double length,
@JsonProperty("width") double width) {
if ("circle".equalsIgnoreCase(type)) {
return new Circle(radius, color);
} else if ("rectangle".equalsIgnoreCase(type)) {
return new Rectangle(length, width, color);
}
throw new IllegalArgumentException("Unknown shape type");
}
}
Polymorphic Deserialization with Custom Factory:
ObjectMapper objectMapper = new ObjectMapper();
Shape shape1 = objectMapper.readValue(jsonCircle, Shape.class);
Shape shape2 = objectMapper.readValue(jsonRectangle, Shape.class);
- Polymorphic Deserialization Jackson এর মাধ্যমে প্যারেন্ট এবং সাবক্লাসের JSON ডেটা থেকে সঠিক অবজেক্ট তৈরি করতে সক্ষম।
@JsonTypeInfoএবং@JsonSubTypesঅ্যানোটেশন ব্যবহার করে আপনি JSON ডেটা থেকে polymorphic অবজেক্ট তৈরি করতে পারেন।- Jackson-এর polymorphic deserialization প্রক্রিয়া সহজ করে তোলে যখন আপনাকে একাধিক ধরনের অবজেক্ট একই প্যারেন্ট টাইপের অধীনে রাখতে হয়।
Read more