Java Technologies @JsonTypeInfo এবং Polymorphic Deserialization গাইড ও নোট

245

@JsonTypeInfo একটি Jackson অ্যানোটেশন যা Polymorphic Deserialization সমর্থন করে। এটি Type Metadata (যেমন একটি type ফিল্ড) JSON ডেটার মধ্যে যোগ করে, যা Jackson কে নির্দিষ্ট ক্লাসের টাইপ সঠিকভাবে ডিটেক্ট করতে সহায়তা করে। এর মাধ্যমে, বিভিন্ন সাবক্লাসের JSON ডেটা সঠিকভাবে Java Object-এ রূপান্তর করা যায়, যদিও তাদের প্যারেন্ট ক্লাসের মাধ্যমে ডেসিরিয়ালাইজ করা হয়।

Polymorphic Deserialization এর ধারণা

Polymorphic Deserialization একটি প্রযুক্তি যা আপনাকে একাধিক সাবক্লাসের JSON ডেটা একটি সাধারণ প্যারেন্ট ক্লাসে Deserialization করতে সাহায্য করে। এতে, Jackson সাবক্লাস টাইপ চিহ্নিত করতে @JsonTypeInfo অ্যানোটেশন ব্যবহার করে এবং সঠিক সাবক্লাসে ডেটা ম্যাপ করে।


@JsonTypeInfo Annotation এর বৈশিষ্ট্য

@JsonTypeInfo অ্যানোটেশনটি JSON ডেটা প্রসেস করার সময় টাইপ ইনফরমেশন সংযোজনের জন্য ব্যবহৃত হয়। এটি JSON অবজেক্টে একটি প্রপার্টি যোগ করে, যা Jackson কে টাইপ ইনফরমেশন জানায় এবং সঠিক ক্লাস ডেসিরিয়ালাইজ করতে সাহায্য করে।

প্রধান প্যারামিটারসমূহ:

প্যারামিটারবর্ণনা
useটাইপ ইনফরমেশন কোথায় সংযুক্ত হবে তা নির্ধারণ করে। (যেমন: Id.NAME, Id.CLASS)
includeটাইপ ইনফরমেশন JSON এ কীভাবে অন্তর্ভুক্ত হবে তা নির্ধারণ করে। (যেমন: As.PROPERTY, As.EXTERNAL_PROPERTY)
propertyJSON ফিল্ডের নাম যা টাইপ ইনফরমেশন ধারণ করবে।

@JsonTypeInfo এর উদাহরণ

১. @JsonTypeInfo এবং @JsonSubTypes এর ব্যবহার

Polymorphic Deserialization জন্য @JsonTypeInfo এবং @JsonSubTypes একসাথে ব্যবহার করা হয়।

  1. @JsonTypeInfo — JSON এর মধ্যে টাইপ ইনফরমেশন যুক্ত করে।
  2. @JsonSubTypes — টাইপ ইনফরমেশন অনুযায়ী সাবক্লাসগুলি চিহ্নিত করে।
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 = Car.class, name = "car"),
    @JsonSubTypes.Type(value = Truck.class, name = "truck")
})
abstract class Vehicle {
    private String brand;

    // Getters and Setters
    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }
}

class Car extends Vehicle {
    private int seatingCapacity;

    // Getters and Setters
    public int getSeatingCapacity() {
        return seatingCapacity;
    }

    public void setSeatingCapacity(int seatingCapacity) {
        this.seatingCapacity = seatingCapacity;
    }
}

class Truck extends Vehicle {
    private int loadCapacity;

    // Getters and Setters
    public int getLoadCapacity() {
        return loadCapacity;
    }

    public void setLoadCapacity(int loadCapacity) {
        this.loadCapacity = loadCapacity;
    }
}

Deserialization Example:

import com.fasterxml.jackson.databind.ObjectMapper;

public class PolymorphicDeserializationExample {
    public static void main(String[] args) throws Exception {
        String carJson = "{\"type\":\"car\",\"brand\":\"Toyota\",\"seatingCapacity\":5}";
        String truckJson = "{\"type\":\"truck\",\"brand\":\"Volvo\",\"loadCapacity\":10000}";

        ObjectMapper objectMapper = new ObjectMapper();

        Vehicle car = objectMapper.readValue(carJson, Vehicle.class);
        Vehicle truck = objectMapper.readValue(truckJson, Vehicle.class);

        System.out.println("Car brand: " + car.getBrand());
        System.out.println("Truck brand: " + truck.getBrand());
    }
}
Output:
Car brand: Toyota
Truck brand: Volvo

এখানে type প্রপার্টি (যা "car" এবং "truck" এর মান ধারণ করে) ব্যবহার করে Jackson সঠিক সাবক্লাস (Car অথবা Truck) নির্ধারণ করেছে।


২. @JsonTypeInfo এর অন্যান্য প্যারামিটার

  1. use = JsonTypeInfo.Id.CLASS: এখানে টাইপ ইনফরমেশন সম্পূর্ণ ক্লাসের নামের মাধ্যমে নির্ধারণ করা হয় (যেমন: com.example.Car), যা class নাম ব্যবহার করে সাবক্লাসটি সনাক্ত করতে সাহায্য করে।
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
  1. include = JsonTypeInfo.As.EXTERNAL_PROPERTY: টাইপ ইনফরমেশন অবজেক্টের বাহিরে (অ্যালাইস হিসেবে) থাকবে।
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")

@JsonTypeInfo এবং @JsonSubTypes এর গুরুত্ব

  • Polymorphic Deserialization:
    • Jackson এই অ্যানোটেশনগুলি ব্যবহার করে একাধিক ক্লাসের ডেটা সঠিকভাবে ডেসিরিয়ালাইজ করতে পারে। এর মাধ্যমে একক প্যারেন্ট ক্লাসের মাধ্যমে বিভিন্ন সাবক্লাসের ডেটা প্রক্রিয়া করা সম্ভব হয়।
  • Maintainability:
    • যখন আপনার ক্লাস হায়ারার্কি থাকে এবং নতুন সাবক্লাস যুক্ত করতে হয়, তখন @JsonTypeInfo এবং @JsonSubTypes ব্যবহার করে আপনি আপনার কোডকে সহজে মেইনটেইন করতে পারবেন।
  • Efficient Data Binding:
    • একাধিক ধরনের JSON ডেটা একটি সাধারণ প্যারেন্ট ক্লাসে Polymorphic Deserialization দিয়ে প্রক্রিয়া করা যায়, যা JSON ফাইলের ভিন্ন ধরনের স্ট্রাকচারকে সহজভাবে ম্যানেজ করতে সাহায্য করে।

@JsonTypeInfo ব্যবহার করার সময়ে কিছু টিপস

  1. Avoid Using @JsonTypeInfo with Large Object Graphs:
    • যখন আপনি একটি বড় অবজেক্ট গ্রাফ বা অনেক সাবক্লাসের সঙ্গে কাজ করছেন, তখন @JsonTypeInfo প্রয়োগের সময় অতিরিক্ত টাইপ ইনফরমেশন জেনারেশন এড়ানোর জন্য সঠিক ভাবে পরিকল্পনা করা উচিত।
  2. Be Careful with @JsonSubTypes:
    • @JsonSubTypes ব্যবহার করার সময় সাবক্লাসগুলোর নাম সঠিকভাবে সেট করুন যাতে Jackson সঠিক ক্লাস সনাক্ত করতে পারে।
  3. Keep the Type Property Consistent:
    • যখন আপনি Polymorphic Deserialization ব্যবহার করেন, তখন JSON ডেটাতে type প্রপার্টির মান সঠিকভাবে সুনির্দিষ্ট করুন যাতে Jackson সঠিকভাবে টাইপ ইনফরমেশন হ্যান্ডেল করতে পারে।
  • @JsonTypeInfo এবং @JsonSubTypes Jackson-এর Polymorphic Deserialization সমর্থন করে, যা আপনাকে বিভিন্ন ধরনের JSON ডেটা একে অপরের সঙ্গে প্রক্রিয়া করতে সাহায্য করে।
  • এটি complex class hierarchies এবং dynamic JSON structures এর জন্য উপকারী, যেখানে আপনি প্যারেন্ট ক্লাসের মাধ্যমে বিভিন্ন সাবক্লাসের JSON ডেটা পড়তে পারেন।
Content added By

Polymorphism এবং Jackson এর মধ্যে এর ব্যবহার

274

Polymorphism হল অবজেক্ট-অরিয়েন্টেড প্রোগ্রামিংয়ের একটি গুরুত্বপূর্ণ ধারণা, যেখানে একটি ক্লাসের সাবক্লাসগুলির বিভিন্ন আচরণ (behavior) একসাথে কাজ করতে পারে। Jackson এ Polymorphism ব্যবহারের মাধ্যমে আমরা বিভিন্ন ধরনের অবজেক্টকে একই ধরনের রেফারেন্স বা ইন্টারফেসে মডেল করতে পারি এবং JSON Serialization এবং Deserialization এর সময় সঠিক ক্লাস ইনস্ট্যান্সে রূপান্তর করতে পারি।

Jackson এর মাধ্যমে Polymorphism-এর জন্য @JsonTypeInfo, @JsonSubTypes, এবং @JsonTypeName অ্যানোটেশনগুলি ব্যবহৃত হয়।


Jackson-এ Polymorphism ব্যবহারের জন্য প্রয়োজনীয় অ্যানোটেশনগুলি

  1. @JsonTypeInfo:
    • এটি নির্ধারণ করে যে JSON ডেটাতে কোন তথ্য (যেমন, টাইপ ইনফরমেশন) সংরক্ষণ করা হবে এবং সেটা কিভাবে হবে।
  2. @JsonSubTypes:
    • এটি Subtypes (সাবক্লাস) এর তালিকা প্রদান করে এবং তাদের নাম চিহ্নিত করে, যাতে Jackson সঠিক ক্লাস রূপান্তর করতে পারে।
  3. @JsonTypeName:
    • এটি একটি নির্দিষ্ট সাবক্লাসের জন্য টাইপ ইনফরমেশন সেট করতে ব্যবহৃত হয়।

Jackson-এ Polymorphism এর উদাহরণ

১. @JsonTypeInfo এবং @JsonSubTypes ব্যবহার করে Polymorphism

ধরা যাক, আমাদের কাছে একটি Vehicle প্যারেন্ট ক্লাস আছে এবং এর দুটি সাবক্লাস: Car এবং Truck। আমরা JSON-এ টাইপ ইনফরমেশন রাখতে চাই, যাতে Jackson সঠিক ক্লাসে রূপান্তর করতে পারে।

Java Class Example:

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,  // Name-based polymorphism
    include = JsonTypeInfo.As.PROPERTY,  // Include type info as a property
    property = "type"  // The name of the property holding type information
)
@JsonSubTypes({
    @JsonSubTypes.Type(value = Car.class, name = "car"),
    @JsonSubTypes.Type(value = Truck.class, name = "truck")
})
public abstract class Vehicle {
    private String brand;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }
}

public class Car extends Vehicle {
    private int seatingCapacity;

    public int getSeatingCapacity() {
        return seatingCapacity;
    }

    public void setSeatingCapacity(int seatingCapacity) {
        this.seatingCapacity = seatingCapacity;
    }
}

public class Truck extends Vehicle {
    private int loadCapacity;

    public int getLoadCapacity() {
        return loadCapacity;
    }

    public void setLoadCapacity(int loadCapacity) {
        this.loadCapacity = loadCapacity;
    }
}

Serialization Example (Java to JSON):

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonPolymorphismExample {
    public static void main(String[] args) throws Exception {
        Car car = new Car();
        car.setBrand("Toyota");
        car.setSeatingCapacity(5);

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(car);
        System.out.println(json);
    }
}

JSON Output:

{
  "type": "car",
  "brand": "Toyota",
  "seatingCapacity": 5
}

Deserialization Example (JSON to Java):

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonPolymorphismExample {
    public static void main(String[] args) throws Exception {
        String json = "{\"type\":\"car\",\"brand\":\"Toyota\",\"seatingCapacity\":5}";

        ObjectMapper mapper = new ObjectMapper();
        Vehicle vehicle = mapper.readValue(json, Vehicle.class);  // Automatically detects the type
        System.out.println(vehicle.getClass().getSimpleName());  // Prints: Car
    }
}

Output:

Car

২. @JsonTypeName ব্যবহার করে Polymorphism

@JsonTypeName অ্যানোটেশন ব্যবহৃত হয় একটি নির্দিষ্ট সাবক্লাসের জন্য টাইপ ইনফরমেশন সেট করতে।

Java Class Example:

import com.fasterxml.jackson.annotation.JsonTypeName;

@JsonTypeName("car")
public class Car extends Vehicle {
    private int seatingCapacity;

    public int getSeatingCapacity() {
        return seatingCapacity;
    }

    public void setSeatingCapacity(int seatingCapacity) {
        this.seatingCapacity = seatingCapacity;
    }
}

@JsonTypeName("truck")
public class Truck extends Vehicle {
    private int loadCapacity;

    public int getLoadCapacity() {
        return loadCapacity;
    }

    public void setLoadCapacity(int loadCapacity) {
        this.loadCapacity = loadCapacity;
    }
}

এখানে, @JsonTypeName("car") এবং @JsonTypeName("truck") ব্যবহার করা হয়েছে, যা JSON-এর টাইপ হিসেবে car এবং truck ইনফরমেশন সংরক্ষণ করবে।

Serialization Example (Java to JSON):

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonPolymorphismExample {
    public static void main(String[] args) throws Exception {
        Truck truck = new Truck();
        truck.setBrand("Volvo");
        truck.setLoadCapacity(10000);

        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(truck);
        System.out.println(json);
    }
}

JSON Output:

{
  "type": "truck",
  "brand": "Volvo",
  "loadCapacity": 10000
}

Deserialization Example (JSON to Java):

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonPolymorphismExample {
    public static void main(String[] args) throws Exception {
        String json = "{\"type\":\"truck\",\"brand\":\"Volvo\",\"loadCapacity\":10000}";

        ObjectMapper mapper = new ObjectMapper();
        Vehicle vehicle = mapper.readValue(json, Vehicle.class);
        System.out.println(vehicle.getClass().getSimpleName());  // Prints: Truck
    }
}

Output:

Truck

Polymorphism এবং Jackson-এ এর ব্যবহার:

  1. @JsonTypeInfo: Jackson কে জানায় যে কিভাবে JSON ডেটাতে টাইপ ইনফরমেশন থাকবে (যেমন, type ফিল্ডে car অথবা truck লেখা হবে)।
  2. @JsonSubTypes: Jackson কে জানায় যে কোন সাবক্লাসগুলি প্যারেন্ট ক্লাসের জন্য বৈধ এবং তাদের জন্য টাইপ নামগুলি কী হবে।
  3. @JsonTypeName: সাবক্লাসে টাইপ ইনফরমেশন সরাসরি ম্যানুয়ালি নির্ধারণ করতে ব্যবহৃত হয়।
  • Polymorphism Jackson-এর মাধ্যমে খুব সহজে পরিচালনা করা যায়। এটি abstract এবং concrete ক্লাসগুলির মধ্যে সঠিকভাবে Serialization এবং Deserialization করার ক্ষমতা প্রদান করে।
  • @JsonTypeInfo, @JsonSubTypes, এবং @JsonTypeName অ্যানোটেশনগুলি Jackson-এ Polymorphism হ্যান্ডলিংয়ের জন্য শক্তিশালী টুল হিসেবে কাজ করে।
  • এটি API ডিজাইন এবং JSON ডেটা রূপান্তরের ক্ষেত্রে কার্যকরী, বিশেষ করে যখন আপনার একটি অ্যাপ্লিকেশনে বিভিন্ন ধরনের অবজেক্ট একত্রে কাজ করতে হয়।
Content added By

@JsonTypeInfo দিয়ে type metadata যোগ করা

307

@JsonTypeInfo Jackson-এর একটি অ্যানোটেশন যা type metadata (অর্থাৎ, অবজেক্টের ধরণ বা type) JSON-এ যোগ করার জন্য ব্যবহৃত হয়। এটি polymorphic serialization/deserialization পরিচালনা করতে সহায়ক, যেখানে একই প্যারেন্ট ক্লাস বা ইন্টারফেসের বিভিন্ন সাবক্লাস বা ইমপ্লিমেন্টেশন একসাথে কাজ করতে পারে।

Jackson ব্যবহার করার সময় যখন একটি ক্লাসের বিভিন্ন সাবক্লাস থাকে এবং আপনি সেগুলি JSON-এ সঠিকভাবে রূপান্তর করতে চান, তখন @JsonTypeInfo অ্যানোটেশনটি প্রয়োজনীয় টাইপ মেটাডেটা যোগ করতে ব্যবহৃত হয়। এর মাধ্যমে, JSON ডেটার মধ্যে সাবক্লাসের টাইপের তথ্য সংযুক্ত করা হয়, যাতে ডেসিরিয়ালাইজেশনের সময় সঠিক ক্লাসে রূপান্তর করা যায়।


@JsonTypeInfo এর প্যারামিটারসমূহ:

  • use: টাইপ ইনফরমেশন যেভাবে হবে তা নির্ধারণ করা (যেমন, Id.NAME, Id.CLASS, Id.MINIMAL_CLASS ইত্যাদি)।
  • include: টাইপ ইনফরমেশন JSON-এ কোথায় থাকবে (যেমন, As.PROPERTY, As.WRAPPER_OBJECT, As.EXTERNAL_PROPERTY)।
  • property: টাইপ ইনফরমেশন JSON প্রপার্টি হিসেবে কী নামে থাকবে।
  • visible: টাইপ ইনফরমেশন ফিল্ড হিসেবে দৃশ্যমান হবে কিনা তা নির্ধারণ করতে ব্যবহৃত হয়।

@JsonTypeInfo এর ব্যবহার

1. Basic Example: Polymorphism

ধরা যাক, আমাদের একটি Shape প্যারেন্ট ক্লাস রয়েছে এবং তার দুটি সাবক্লাস Circle এবং Rectangle রয়েছে। আমরা চাই, যে JSON ডেটা একে অপরের সাথে interchange করতে পারে এবং সঠিক টাইপ ডেসিরিয়ালাইজ করতে সক্ষম হবে।

কোড উদাহরণ:

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,  // টাইপের নাম হিসেবে ব্যবহার হবে (এখানে "name" এর মাধ্যমে)
    include = JsonTypeInfo.As.PROPERTY,  // টাইপ ইনফরমেশন JSON এর একটি প্রপার্টি হিসেবে থাকবে
    property = "shape_type"  // টাইপ ইনফরমেশন JSON এ "shape_type" হিসেবে থাকবে
)
@JsonSubTypes({
    @Type(value = Circle.class, name = "circle"),
    @Type(value = Rectangle.class, name = "rectangle")
})
abstract class Shape {
    public abstract double area();
}

class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
}

class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double area() {
        return width * height;
    }

    public double getWidth() {
        return width;
    }

    public void setWidth(double width) {
        this.width = width;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }
}

Serialization Example:

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonTypeInfoExample {
    public static void main(String[] args) throws Exception {
        Shape shape = new Circle(5.0);  // Circle এর একটি অবজেক্ট

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(shape);
        System.out.println("Serialized JSON: " + json);
    }
}

JSON Output:

{
  "shape_type": "circle",
  "radius": 5.0
}

ব্যাখ্যা:

  • @JsonTypeInfo ব্যবহার করার মাধ্যমে Shape অবজেক্টের shape_type প্রপার্টি হিসেবে টাইপ ইনফরমেশন (যেমন "circle") JSON-এ যোগ করা হয়েছে।
  • এটি polymorphic types (এখানে Circle এবং Rectangle) JSON-এর মধ্যে সংযুক্ত করার একটি সহজ উপায়।

2. Deserialization Example

JSON থেকে Shape অবজেক্ট ডেসিরিয়ালাইজ করার সময়, shape_type অনুযায়ী সঠিক সাবক্লাসে রূপান্তর করা হবে।

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonTypeInfoDeserializationExample {
    public static void main(String[] args) throws Exception {
        String json = "{\"shape_type\":\"circle\",\"radius\":5.0}";

        ObjectMapper objectMapper = new ObjectMapper();
        Shape shape = objectMapper.readValue(json, Shape.class);
        System.out.println("Deserialized Shape: " + shape.getClass().getName());
        System.out.println("Area: " + shape.area());
    }
}

Output:

Deserialized Shape: Circle
Area: 78.53981633974483

ব্যাখ্যা:

  • Jackson JSON থেকে Shape অবজেক্ট ডেসিরিয়ালাইজ করার সময় shape_type ফিল্ডের মান অনুযায়ী সঠিক ক্লাস (Circle) নির্বাচন করেছে।

@JsonTypeInfo এর বিভিন্ন use এবং include অপশন

Jackson-এ @JsonTypeInfo এর বিভিন্ন কনফিগারেশন অপশন রয়েছে, যেগুলি আপনার প্রয়োজন অনুসারে টাইপ ইনফরমেশন কাস্টমাইজ করতে সাহায্য করে:

1. use = JsonTypeInfo.Id.CLASS

এটি ক্লাসের পূর্ণ নাম ব্যবহার করে টাইপ ইনফরমেশন সংযুক্ত করে।

@JsonTypeInfo(
    use = JsonTypeInfo.Id.CLASS,
    include = JsonTypeInfo.As.PROPERTY,
    property = "shape_type"
)

2. include = JsonTypeInfo.As.WRAPPER_OBJECT

এটি JSON এর অবজেক্টের মধ্যে টাইপ ইনফরমেশনকে wrap করে রাখে।

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.WRAPPER_OBJECT,
    property = "shape_type"
)

Output (Wrapper Object) Example:

{
  "shape_type": {
    "radius": 5.0
  }
}

3. @JsonSubTypes ব্যবহার

@JsonSubTypes ব্যবহার করে আপনি টাইপ ইনফরমেশন-সহ বিভিন্ন সাবক্লাস নির্দিষ্ট করতে পারেন। এর মাধ্যমে polymorphic deserialization পরিচালনা করা সহজ হয়।

@JsonSubTypes({
    @Type(value = Circle.class, name = "circle"),
    @Type(value = Rectangle.class, name = "rectangle")
})

@JsonTypeInfo এর সুবিধা

  1. Polymorphic Serialization এবং Deserialization:
    • এটি polymorphic অবজেক্টের ক্ষেত্রে টাইপ ইনফরমেশন JSON-এ সংযুক্ত করতে সহায়ক।
  2. Type Discriminator:
    • JSON ডেটাতে টাইপ ডিসক্রিমিনেটর (type discriminator) যোগ করতে পারে, যা ডেসিরিয়ালাইজেশনের সময় সঠিক ক্লাস নির্বাচন করতে সাহায্য করে।
  3. Customizable Type Information:
    • use, include, এবং property এর মাধ্যমে টাইপ ইনফরমেশন কাস্টমাইজ করা যায়।
  4. Backward Compatibility:
    • যখন বিভিন্ন সাবক্লাস ব্যবহার হয়, তখন Jackson আপনাকে সাবক্লাসের টাইপ ইনফরমেশন JSON-এ সঠিকভাবে অন্তর্ভুক্ত করতে সহায়তা করে, যা পরিবর্তনশীল ডেটা ফরম্যাট বা API পরিবর্তনগুলোর জন্য সহায়ক।

  • @JsonTypeInfo অ্যানোটেশনটি polymorphic serialization এবং deserialization-এর জন্য অত্যন্ত উপকারী। এটি JSON-এ টাইপ ইনফরমেশন সংযুক্ত করে, যার ফলে Jackson সঠিক সাবক্লাস ডেসিরিয়ালাইজ করতে সক্ষম হয়।
  • এর মাধ্যমে, আপনি বিভিন্ন ধরনের অবজেক্টের সাথে কাজ করার জন্য JSON ডেটার স্ট্রাকচার এবং টাইপ কাস্টমাইজ করতে পারেন।
  • @JsonSubTypes এবং @JsonTypeInfo এর সঠিক ব্যবহার polymorphic object handling সহজ করে তোলে।
Content added By

@JsonSubTypes এর মাধ্যমে subclass deserialization

283

@JsonSubTypes Jackson এর একটি শক্তিশালী অ্যানোটেশন, যা Polymorphic Deserialization-এ সাহায্য করে। এটি মূলত একটি parent class এবং তার subclasses এর মধ্যে সম্পর্ক নির্ধারণ করতে ব্যবহৃত হয়। যখন একটি superclass থেকে subclasses এ ডেটা ম্যাপ করতে হয়, তখন @JsonSubTypes ব্যবহার করে subclasses এর dynamic type handling করা যায়।

Polymorphic Deserialization

Polymorphic Deserialization হল এমন একটি প্রক্রিয়া যেখানে একটি সাধারণ (parent) ক্লাসের ইনস্ট্যান্স JSON ফরম্যাটে উপস্থিত থাকে এবং তা থেকে সঠিক subclass তৈরি করা হয়।

Jackson @JsonSubTypes এবং @JsonTypeInfo অ্যানোটেশনগুলির সাহায্যে polymorphic deserialization সক্ষম করে, যেখানে superclass JSON ডেটা থেকে তার subtype খুঁজে বের করে এবং সেই অনুযায়ী subclass-এর ইনস্ট্যান্স তৈরি করে।


@JsonSubTypes এর মূল বৈশিষ্ট্য

  • Dynamic Type Identification: Jackson parent class থেকে সঠিক subclass ডেসিরিয়ালাইজ করতে পারে।
  • Type Information: @JsonTypeInfo এর মাধ্যমে টাইপ ইনফরমেশন দেওয়া হয়, যাতে Jackson সঠিক subclass নির্বাচন করতে পারে।
  • Subtypes Configuration: @JsonSubTypes ব্যবহার করে আপনি subclass গুলো নির্দিষ্ট করতে পারেন।

@JsonSubTypes এর ব্যবহার

Step-by-Step উদাহরণ:

  1. Superclass তৈরি করা (Parent Class):
    • প্রথমে একটি superclass (Parent Class) তৈরি করুন।
  2. Subclass তৈরি করা:
    • এরপর এই superclass থেকে একাধিক subclass তৈরি করুন।
  3. @JsonTypeInfo এবং @JsonSubTypes ব্যবহার করা:
    • @JsonTypeInfo parent class-এ ব্যবহার করা হবে, যা ডেটাতে টাইপ ইনফরমেশন রাখে।
    • @JsonSubTypes ব্যবহার করে subclass গুলো নির্ধারণ করা হবে।

১. Superclass এবং Subclasses তৈরি করা

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 = Dog.class, name = "dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public abstract void makeSound();
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeSound() {
        System.out.println("Meow");
    }
}

২. JSON Serialization (Superclass এর Object এর JSON রূপান্তর)

import com.fasterxml.jackson.databind.ObjectMapper;

public class PolymorphicSerializationExample {
    public static void main(String[] args) throws Exception {
        Animal dog = new Dog("Buddy");
        Animal cat = new Cat("Whiskers");

        ObjectMapper mapper = new ObjectMapper();

        // Serialize to JSON
        String dogJson = mapper.writeValueAsString(dog);
        String catJson = mapper.writeValueAsString(cat);

        System.out.println("Dog JSON: " + dogJson);
        System.out.println("Cat JSON: " + catJson);
    }
}

Output:

Dog JSON: {"type":"dog","name":"Buddy"}
Cat JSON: {"type":"cat","name":"Whiskers"}

এখানে @JsonTypeInfo অ্যানোটেশনটি type ফিল্ডের মাধ্যমে subclass টাইপ ইনফরমেশন সরবরাহ করেছে, এবং @JsonSubTypes ডগ এবং ক্যাট subclass গুলো নির্ধারণ করেছে।


৩. JSON Deserialization (JSON থেকে Subclass Object তৈরি)

import com.fasterxml.jackson.databind.ObjectMapper;

public class PolymorphicDeserializationExample {
    public static void main(String[] args) throws Exception {
        String dogJson = "{\"type\":\"dog\",\"name\":\"Buddy\"}";
        String catJson = "{\"type\":\"cat\",\"name\":\"Whiskers\"}";

        ObjectMapper mapper = new ObjectMapper();

        // Deserialize JSON back to correct subclass
        Animal dog = mapper.readValue(dogJson, Animal.class);
        Animal cat = mapper.readValue(catJson, Animal.class);

        System.out.println("Dog Name: " + dog.getName());
        dog.makeSound();

        System.out.println("Cat Name: " + cat.getName());
        cat.makeSound();
    }
}

Output:

Dog Name: Buddy
Bark
Cat Name: Whiskers
Meow

এখানে, Jackson type প্রোপার্টির মাধ্যমে সঠিক subclass (Dog অথবা Cat) নির্বাচন করেছে এবং তারপরে সঠিক subclass-এর অবজেক্ট তৈরি করেছে।


@JsonSubTypes এর গুরুত্বপূর্ণ প্যারামিটারসমূহ

  1. value:
    • এটি subclass কে সুনির্দিষ্ট করে। এখানে আমরা Dog.class এবং Cat.class প্রদান করেছি।
  2. name:
    • এটি subclass টাইপের নাম নির্ধারণ করে। এখানে "dog" এবং "cat" আমরা JSON ডেটার মধ্যে প্রদান করেছি।
  3. use:
    • JsonTypeInfo.Id.NAME ব্যবহার করলে টাইপ ইনফরমেশন হিসেবে subclass নাম প্রেরণ হয়।
    • অন্য একটি ব্যবহার হতে পারে JsonTypeInfo.Id.CLASS, যেখানে ক্লাসের সম্পূর্ণ নাম ব্যবহৃত হয়।

@JsonTypeInfo এবং @JsonSubTypes এর অতিরিক্ত কনফিগারেশন

Polymorphic Type Handling with Class Names

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class, name = "com.example.Dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "com.example.Cat")
})
public abstract class Animal { ... }

এখানে, @JsonTypeInfo.Id.CLASS ব্যবহারের মাধ্যমে Jackson পুরো ক্লাসের নাম (যেমন: "com.example.Dog") ব্যবহার করবে subclass সনাক্ত করতে।

Polymorphic Deserialization using @JsonSubTypes with Constructor

@JsonSubTypes({
    @JsonSubTypes.Type(value = Dog.class, name = "dog"),
    @JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public abstract class Animal {
    private String name;
    
    // Constructor, Getters, and Setters
    
    @JsonCreator
    public Animal(@JsonProperty("name") String name) {
        this.name = name;
    }
}

এখানে, @JsonCreator এবং @JsonProperty ব্যবহার করে কাস্টম কনস্ট্রাকটর দিয়ে ডেসিরিয়ালাইজেশন করা যেতে পারে।


  1. Polymorphic Deserialization সহজে Jackson দিয়ে @JsonTypeInfo এবং @JsonSubTypes ব্যবহার করে করা সম্ভব।
  2. @JsonSubTypes আপনাকে JSON ফাইলের বিভিন্ন subclass টাইপ অনুযায়ী সঠিক Java ক্লাসে ডেটা ম্যাপ করতে সাহায্য করে।
  3. Type Information এবং Subtypes Configuration এর মাধ্যমে আপনি বিভিন্ন subclass ইনস্ট্যান্স তৈরি করতে পারেন, যা বিশেষত polymorphic ডেটা মডেল এবং API-তে খুবই উপকারী।
Content added By

উদাহরণ সহ Polymorphic Deserialization এর প্রয়োগ

278

Polymorphic Deserialization হলো সেই প্রক্রিয়া, যেখানে একটি সাধারণ প্যারেন্ট ক্লাস বা ইন্টারফেসের ইনস্ট্যান্সকে JSON ডেটা থেকে সঠিক সাবক্লাসের ইনস্ট্যান্সে রূপান্তর করা হয়। Jackson-এ polymorphic deserialization সহজভাবে @JsonTypeInfo এবং @JsonSubTypes অ্যানোটেশন ব্যবহার করে করা যায়।

এটি subtype এর উপর ভিত্তি করে parent class-এর deserialization প্রক্রিয়া নিয়ন্ত্রণ করতে সাহায্য করে। এটি কার্যকর যখন আপনার অনেক ধরনের অবজেক্ট থাকে, কিন্তু আপনি তাদের একে অপরের সাবক্লাস হিসেবে কাজ করাতে চান।


Jackson-এ Polymorphic Deserialization করতে @JsonTypeInfo এবং @JsonSubTypes ব্যবহার

@JsonTypeInfo

  • @JsonTypeInfo Jackson-কে বলে যে ফিল্ডটি 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:

  1. @JsonTypeInfo:
    • use = JsonTypeInfo.Id.NAME → এটি নির্দেশ করে যে টোকেন হিসেবে একটি নাম (এখানে type) ব্যবহার করা হবে।
    • include = JsonTypeInfo.As.PROPERTY → এটি JSON-এ টোকেনটি একটি প্রপার্টি হিসেবে ইনক্লুড করবে।
    • property = "type" → টোকেনের নাম যা JSON এ থাকবে।
  2. @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 প্রক্রিয়া সহজ করে তোলে যখন আপনাকে একাধিক ধরনের অবজেক্ট একই প্যারেন্ট টাইপের অধীনে রাখতে হয়।
Content added By
Promotion

Are you sure to start over?

Loading...