Java Technologies Exception Handling in Jackson গাইড ও নোট

383

Jackson ব্যবহার করার সময় exception handling গুরুত্বপূর্ণ, কারণ এটি JSON Serialization এবং Deserialization-এর সময় বিভিন্ন ধরনের ভুল বা সমস্যার সৃষ্টি করতে পারে। যেমন: invalid JSON format, missing fields, type mismatches, unknown properties, ইত্যাদি। Jackson অনেক ধরনের exception থ্রো করতে পারে, এবং এই exception গুলো সঠিকভাবে হ্যান্ডেল করা খুবই গুরুত্বপূর্ণ।

Jackson এর exception handling কার্যকরভাবে করার জন্য আমরা কিছু অ্যানোটেশন এবং ObjectMapper কনফিগারেশন ব্যবহার করতে পারি।


Jackson Exception Types

Jackson বিভিন্ন ধরনের exception থ্রো করতে পারে, কিছু সাধারণ exceptions হলো:

  1. JsonParseException:
    • এটি সাধারণত তখন ঘটে যখন JSON স্ট্রিংটি সঠিকভাবে ফর্ম্যাট করা হয় না (যেমন: ভুল সিঙ্গল কোটেশন, অনুপস্থিত ক্লোজিং ব্রেসেস ইত্যাদি)।
  2. JsonMappingException:
    • এটি তখন ঘটে যখন Jackson একটি JSON ডেটাকে নির্দিষ্ট Java অবজেক্টে ম্যাপ করতে ব্যর্থ হয় (যেমন: ফিল্ডের টাইপের মিল না হওয়া)।
  3. JsonProcessingException:
    • এটি সাধারণ superclass যা অন্য সকল exception class গুলোকে একত্রিত করে।
  4. JsonGenerationException:
    • এটি সাধারণত তখন ঘটে যখন JSON জেনারেট করার সময় কোনো সমস্যা হয়।

Exception Handling উদাহরণ

1. JsonParseException (Invalid JSON Format)

উদাহরণ: যদি JSON এর মধ্যে ভুল ফরম্যাট থাকে, যেমন অতিরিক্ত বা ভুল কোটেশন, অথবা ভুল ব্রেসেস থাকে।

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonParseException;

public class JsonParseExceptionExample {
    public static void main(String[] args) {
        String invalidJson = "{\"name\":\"Rahim\", \"age\":30"; // Missing closing brace

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Trying to deserialize invalid JSON
            objectMapper.readValue(invalidJson, User.class);
        } catch (JsonParseException e) {
            System.out.println("Error: Invalid JSON format - " + e.getMessage());
        } catch (Exception e) {
            System.out.println("General error: " + e.getMessage());
        }
    }
}

class User {
    private String name;
    private int age;

    // Getters and Setters
}

Output:

Error: Invalid JSON format - Unexpected character ('}' (code 125)): expected a valid value (number, String, array, object, etc.)

2. JsonMappingException (Mismatch Between JSON and Java Object)

উদাহরণ: যদি JSON ফিল্ডের টাইপ Java অবজেক্টের সাথে মেলে না, যেমন একটি String ফিল্ড JSON-এ কিন্তু Java ক্লাসে সেটা Integer হিসেবে ডিফাইন করা।

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonMappingException;

public class JsonMappingExceptionExample {
    public static void main(String[] args) {
        String json = "{\"name\":\"Rahim\", \"age\":\"30\"}"; // age is given as a String in JSON, but we expect an Integer

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Trying to deserialize a JSON string into a User object where age is expected to be Integer
            objectMapper.readValue(json, User.class);
        } catch (JsonMappingException e) {
            System.out.println("Error: Type mismatch - " + e.getMessage());
        } catch (Exception e) {
            System.out.println("General error: " + e.getMessage());
        }
    }
}

class User {
    private String name;
    private int age;

    // Getters and Setters
}

Output:

Error: Type mismatch - Cannot deserialize value of type `int` from String "30": not a valid Integer value

3. JsonProcessingException (General Error Handling)

Jackson-এর সমস্ত exception এর superclass হল JsonProcessingException। এটি সাধারণত JSON Processing এর অন্য যে কোনো ধরনের ভুলের জন্য ব্যবহার করা হয়।

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

public class JsonProcessingExceptionExample {
    public static void main(String[] args) {
        String invalidJson = "{id: 1, name: Rahim}"; // Invalid JSON format (missing quotes around field names)

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            objectMapper.writeValueAsString(invalidJson); // This will cause JsonProcessingException
        } catch (JsonProcessingException e) {
            System.out.println("Error: JSON Processing failure - " + e.getMessage());
        }
    }
}

Output:

Error: JSON Processing failure - Can not start any event. (through reference chain: java.lang.String)

Jackson Exception Handling: Best Practices

  1. @JsonIgnoreProperties(ignoreUnknown = true):
    • আপনি যদি চান যে JSON ডেটার অজানা ফিল্ডগুলো উপেক্ষা করা হোক, তাহলে @JsonIgnoreProperties ব্যবহার করুন। এটি ডেসিরিয়ালাইজেশনের সময় অজানা প্রপার্টি উপেক্ষা করবে।
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
    private String name;
    private int age;

    // Getters and Setters
}
  1. Global ObjectMapper Configuration:
    • আপনি ObjectMapper এর মাধ্যমে গ্লোবাল কনফিগারেশন তৈরি করতে পারেন, যাতে ডেসিরিয়ালাইজেশন সময় অজানা প্রপার্টি উপেক্ষা করা হয়।
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  1. Custom Exception Handling:
    • Jackson ডেসিরিয়ালাইজেশনের সময় Custom Exception Handling প্রয়োগ করুন, যেমন কাস্টম এরর মেসেজ বা অন্য ধরনের exception ফেলার জন্য।
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

public class CustomExceptionHandler {
    public static void main(String[] args) {
        String invalidJson = "{\"id\":1, \"name\":\"Rahim\"";

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            objectMapper.readValue(invalidJson, User.class);
        } catch (JsonProcessingException e) {
            System.out.println("Custom error handling: " + e.getMessage());
        }
    }
}

@JsonDeserialize এবং @JsonSerialize ব্যবহার করে Custom Error Handling

Jackson এর @JsonDeserialize এবং @JsonSerialize অ্যানোটেশন ব্যবহার করে আপনি কাস্টম deserialization বা serialization প্রক্রিয়া তৈরি করতে পারেন। আপনি এতে exception handling এর জন্য কাস্টম লজিক যুক্ত করতে পারবেন।

Custom Deserializer Example:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

import java.io.IOException;

public class User {
    private String name;
    private int age;

    @JsonDeserialize(using = CustomAgeDeserializer.class)
    public void setAge(String age) {
        this.age = Integer.parseInt(age);
    }

    // Getters and Setters
}

class CustomAgeDeserializer extends JsonDeserializer<Integer> {
    @Override
    public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String ageStr = p.getText();
        try {
            return Integer.parseInt(ageStr);
        } catch (NumberFormatException e) {
            throw new IOException("Invalid age format");
        }
    }
}

  • Jackson exception handling অত্যন্ত গুরুত্বপূর্ণ যখন আপনি JSON ডেটার সাথে কাজ করেন। সাধারণত JsonParseException, JsonMappingException, JsonProcessingException ইত্যাদি প্রধান exception types গুলি আপনার সাথে থাকতে পারে।
  • @JsonIgnoreProperties, ObjectMapper কনফিগারেশন, Custom Exception Handling, এবং Custom Deserializer/Serializer ব্যবহারের মাধ্যমে আপনি Jackson এ exception গুলো কার্যকরভাবে হ্যান্ডেল করতে পারেন।
Content added || updated By

Serialization এবং Deserialization এর সময় Exception Handling

282

Jackson Serialization (Java Object থেকে JSON) এবং Deserialization (JSON থেকে Java Object) এর সময় বিভিন্ন ধরনের Exception ঘটতে পারে। এই exceptions গুলো invalid data format, missing required fields, type mismatches, এবং circular references সহ আরও অনেক কারণে হতে পারে।

Jackson-এ exception handling-কে কাস্টমাইজ করা যেতে পারে, যেমন @JsonProperty, @JsonDeserialize, @JsonSerialize, এবং @JsonIgnoreProperties অ্যানোটেশন ব্যবহার করে।

এছাড়া, Jackson-এর JsonProcessingException, JsonParseException, JsonMappingException এর মতো built-in exceptions ব্যবহৃত হয়, যা JSON-এ রূপান্তরের সময় সঠিকভাবে exception ট্র্যাক করতে সহায়তা করে।


Jackson Serialization এবং Deserialization Exception Handling:

১. JSON Parse Exceptions

যখন JSON স্ট্রিং-এ কোনো ত্রুটি থাকে বা তা অবৈধ (invalid) হয়, তখন JsonParseException বা JsonMappingException ঘটতে পারে।

উদাহরণ: Invalid JSON Format
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonParseException;

public class JsonParseExceptionExample {
    public static void main(String[] args) {
        String invalidJson = "{name: 'John Doe', age: 30}";  // Invalid JSON (missing quotes around field names)

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Invalid JSON Parsing
            objectMapper.readValue(invalidJson, Person.class);
        } catch (JsonParseException e) {
            System.out.println("Invalid JSON Format: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String name;
    private int age;

    // Getters and Setters
}
Output:
Invalid JSON Format: Unexpected character ('n' (code 110)): was expecting double-quote to start field name
  • Explanation: এখানে, JSON স্ট্রিং-এ ফিল্ড নামের চারপাশে ডাবল কোটেশন মার্কস (quotes) নেই, তাই JsonParseException ঘটছে।

২. Missing Required Fields (Deserialization Error)

যখন JSON থেকে একটি অবজেক্ট ডেসিরিয়ালাইজ করা হয় এবং কোনো প্রয়োজনীয় ফিল্ড অনুপস্থিত থাকে, তখন JsonMappingException ঘটতে পারে।

উদাহরণ: Missing Required Fields
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonMappingException;

public class JsonMappingExceptionExample {
    public static void main(String[] args) {
        String json = "{\"name\":\"John Doe\"}";  // Missing age field

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Deserialization: Missing "age" field
            Person person = objectMapper.readValue(json, Person.class);
        } catch (JsonMappingException e) {
            System.out.println("Missing required field: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String name;
    private int age;  // Age is required

    // Getters and Setters
}
Output:
Missing required field: Can not construct instance of com.example.Person: no suitable constructor found, can not deserialize from Object value (no delegate- or property-based creator)
  • Explanation: এখানে, age ফিল্ড JSON-এ অনুপস্থিত, যা Person ক্লাসে required হিসেবে কনফিগার করা ছিল, ফলে JsonMappingException ঘটেছে।

৩. @JsonProperty দিয়ে Required Fields নির্ধারণ

আপনি @JsonProperty(required = true) ব্যবহার করে একটি ফিল্ডকে required হিসেবে চিহ্নিত করতে পারেন, যা Deserialization এর সময় ফিল্ড অনুপস্থিত থাকলে Exception throw করবে।

উদাহরণ:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonMappingException;

public class JsonPropertyRequiredExample {
    public static void main(String[] args) {
        String json = "{\"name\":\"John Doe\"}";  // Missing "age" field

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Deserialization with @JsonProperty(required = true)
            Person person = objectMapper.readValue(json, Person.class);
        } catch (JsonMappingException e) {
            System.out.println("Required field missing: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String name;

    @JsonProperty(required = true)
    private int age;  // Required field

    // Getters and Setters
}
Output:
Required field missing: Missing required creator property 'age' (index 1)
  • Explanation: @JsonProperty(required = true) ব্যবহার করার কারণে age ফিল্ডটি JSON থেকে অনুপস্থিত থাকলে exception ঘটবে।

৪. Circular References Handling (Avoiding Infinite Recursion)

Circular references JSON Serialization এবং Deserialization এর সময় সমস্যা সৃষ্টি করতে পারে। Jackson-এ @JsonManagedReference এবং @JsonBackReference ব্যবহার করে Circular references এড়ানো যায়।

উদাহরণ:
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;

public class Person {
    private String name;

    @JsonManagedReference
    private Address address;

    // Constructor, Getters, Setters
}

public class Address {
    private String street;

    @JsonBackReference
    private Person person;

    // Constructor, Getters, Setters
}
Serialization Example:
import com.fasterxml.jackson.databind.ObjectMapper;

public class CircularReferenceExample {
    public static void main(String[] args) throws Exception {
        Person person = new Person("John Doe", new Address("123 Elm St", null));
        Address address = person.getAddress();
        address.setPerson(person);

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(person);

        System.out.println(json);
    }
}
JSON Output:
{
  "name": "John Doe",
  "address": {
    "street": "123 Elm St"
  }
}
  • Explanation: @JsonManagedReference এবং @JsonBackReference ব্যবহার করার ফলে Circular reference গুলো JSON Serialization থেকে বাদ দেওয়া হয়েছে।

5. Custom Exception Handling

Jackson এর মাধ্যমে কাস্টম Exception Handling করতে হলে আপনি নিজস্ব Exception class তৈরি করে Jackson এর JsonProcessingException এবং JsonMappingException ব্যবহার করতে পারেন।

উদাহরণ:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonProcessingException;

public class CustomExceptionExample {
    public static void main(String[] args) {
        String json = "{\"name\":\"John Doe\",\"age\":\"abc\"}";  // Invalid age format

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // Deserialization with invalid data
            Person person = objectMapper.readValue(json, Person.class);
        } catch (JsonProcessingException e) {
            System.out.println("Custom Error: Invalid data format: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

class Person {
    private String name;
    private int age;

    // Getters and Setters
}
Output:
Custom Error: Invalid data format: Cannot deserialize value of type `int` from String "abc": not a valid Integer value

  • Exception Handling Jackson-এ গুরুত্বপূর্ণ একটি বিষয়। JSON থেকে Java Object এবং Java Object থেকে JSON-এ রূপান্তরের সময় বিভিন্ন ধরনের Exception ঘটতে পারে, যেমন invalid format, missing required fields, type mismatch, এবং Circular references
  • Jackson-এ JsonParseException, JsonMappingException, JsonProcessingException ব্যবহার করে এই Exception গুলো ট্র্যাক করা যায় এবং কাস্টম Exception Handling বাস্তবায়ন করা যায়।
  • @JsonProperty, @JsonManagedReference, @JsonBackReference ইত্যাদি অ্যানোটেশন ব্যবহার করে আপনি Exception Handling আরও কাস্টমাইজ করতে পারেন।

Jackson লাইব্রেরি ব্যবহার করার সময় কিছু সাধারণ সমস্যা দেখা দিতে পারে, বিশেষ করে JSON Serialization এবং Deserialization এর প্রক্রিয়া চলাকালে। এই সমস্যা গুলো সাধারণত mapping issues, missing fields, invalid data types, বা circular references ইত্যাদি থেকে তৈরি হয়।

উপসংহার

Content added || updated By

Common Jackson Errors এবং তাদের সমাধান

237

Jackson লাইব্রেরি ব্যবহার করার সময় কিছু সাধারণ সমস্যা দেখা দিতে পারে, বিশেষ করে JSON Serialization এবং Deserialization এর প্রক্রিয়া চলাকালে। এই সমস্যা গুলো সাধারণত mapping issues, missing fields, invalid data types, বা circular references ইত্যাদি থেকে তৈরি হয়।

এখানে কিছু সাধারণ Jackson ত্রুটি এবং তাদের সমাধান দেওয়া হলো:


1. UnrecognizedPropertyException - Unknown Properties

সমস্যা:

যখন Jackson একটি JSON অবজেক্ট থেকে একটি Java Object-এ ডেটা ডেসিরিয়ালাইজ করার সময়, কিন্তু JSON অবজেক্টে এমন একটি ফিল্ড থাকে যেটি Java ক্লাসে নির্ধারিত নেই, তখন UnrecognizedPropertyException ত্রুটি হয়।

ত্রুটির উদাহরণ:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class User), not marked as ignorable

সমাধান:

  1. @JsonIgnoreProperties ব্যবহার করে অজানা প্রোপার্টি উপেক্ষা করুন।
    • এটি ignoreUnknown অপশন দিয়ে আপনি JSON থেকে অজানা প্রোপার্টি সঠিকভাবে বাদ দিতে পারেন।
  2. @JsonProperty ব্যবহার করে JSON ফিল্ডের নাম সঠিকভাবে মেপিং করুন।

কোড উদাহরণ:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
    private String name;
    private int age;

    // Getters and Setters
}

JSON Example:

{
  "name": "John",
  "age": 30,
  "gender": "male"  // This field will be ignored
}

2. InvalidFormatException - Invalid Data Format

সমস্যা:

এটি তখন ঘটে যখন JSON ডেটার ফরম্যাট এবং Java ক্লাসের ডেটা টাইপ মিলে না। উদাহরণস্বরূপ, আপনি একটি String থেকে int এ ডেসিরিয়ালাইজ করার চেষ্টা করলে এই ত্রুটি হতে পারে।

ত্রুটির উদাহরণ:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `int` from String "abc": not a valid integer value

সমাধান:

  1. JSON ফরম্যাট ঠিক করা: JSON ফিল্ডটি সঠিক ডেটা টাইপে রূপান্তর করুন।
  2. @JsonFormat বা @JsonDeserialize ব্যবহার করুন: আপনি কাস্টম ডেটা ফরম্যাট নির্ধারণ করতে পারেন।

কোড উদাহরণ:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class User {
    private String name;
    
    @JsonDeserialize(using = CustomDateDeserializer.class)
    private Date birthDate;

    // Getters and Setters
}

Custom Deserializer:

import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CustomDateDeserializer extends JsonDeserializer<Date> {
    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = p.getText();
        try {
            return sdf.parse(date);
        } catch (Exception e) {
            throw new IOException("Invalid date format");
        }
    }
}

3. JsonMappingException - Incorrect Field Mapping

সমস্যা:

JsonMappingException তখন ঘটে যখন Jackson একটি JSON অবজেক্টকে Java ক্লাসে রূপান্তর করতে পারে না। সাধারণত এটি সঠিক field mapping বা getter/setter এর অভাবের কারণে হয়।

ত্রুটির উদাহরণ:

com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class User]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)

সমাধান:

  1. Default Constructor নিশ্চিত করুন।
  2. Getter এবং Setter Method নিশ্চিত করুন।
  3. @JsonProperty বা @JsonCreator ব্যবহার করুন যদি আপনি কাস্টম কনস্ট্রাক্টর ব্যবহার করেন।

কোড উদাহরণ:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    private String name;
    private int age;

    @JsonCreator
    public User(@JsonProperty("name") String name, @JsonProperty("age") int age) {
        this.name = name;
        this.age = age;
    }

    // Getters and Setters
}

4. NullPointerException - Null Field Handling

সমস্যা:

এটি তখন ঘটে যখন আপনি একটি null ফিল্ডকে অপর্যাপ্তভাবে ডেসিরিয়ালাইজ করার চেষ্টা করেন, অথবা null ডেটা সেটের জন্য কোন ডিফল্ট মানের ব্যবস্থা না থাকে।

ত্রুটির উদাহরণ:

java.lang.NullPointerException: Cannot invoke "java.lang.String.length()" because "name" is null

সমাধান:

  1. @JsonInclude ব্যবহার করে null ফিল্ডে default behavior নির্ধারণ করা।
  2. @JsonProperty ব্যবহার করে null ফিল্ডের জন্য ডিফল্ট মান সেট করুন।

কোড উদাহরণ:

import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
    private String name;

    public String getName() {
        return name;
    }

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

JSON Example:

{
  "name": null
}

5. StackOverflowError - Circular References

সমস্যা:

যখন আপনি দুটি অবজেক্টকে একে অপরকে রেফার করেন (bi-directional references), তখন StackOverflowError হতে পারে যদি circular reference ঠিকভাবে ম্যানেজ না করা হয়।

ত্রুটির উদাহরণ:

java.lang.StackOverflowError: null

সমাধান:

  1. @JsonManagedReference এবং @JsonBackReference ব্যবহার করে circular references এড়ানো।
  2. @JsonIdentityInfo ব্যবহার করে object ID নির্ধারণ করা।

কোড উদাহরণ:

import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;

public class Person {
    private String name;
    
    @JsonManagedReference
    private Address address;
    
    // Getters and Setters
}

public class Address {
    private String street;
    
    @JsonBackReference
    private Person person;
    
    // Getters and Setters
}

Serialization Example:

import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonReferenceExample {
    public static void main(String[] args) throws Exception {
        Person person = new Person();
        person.setName("John Doe");

        Address address = new Address();
        address.setStreet("1234 Elm St");

        person.setAddress(address);
        address.setPerson(person);

        ObjectMapper objectMapper = new ObjectMapper();
        String json = objectMapper.writeValueAsString(person);
        System.out.println(json);
    }
}

Jackson-এ বিভিন্ন ত্রুটি সাধারণত data mismatches, invalid formats, missing fields এবং circular references থেকে হয়। উপরের সমাধানগুলো আপনাকে এই সমস্যা গুলি সমাধান করতে সহায়তা করবে। সাধারণভাবে:

  • @JsonProperty, @JsonIgnoreProperties, এবং @JsonInclude ব্যবহার করে আপনি আপনার JSON ফাইলের কাঠামো নিয়ন্ত্রণ করতে পারেন।
  • @JsonManagedReference এবং @JsonBackReference circular references ব্লক করতে সাহায্য করে।
  • Default constructors এবং getter/setter methods নিশ্চিত করার মাধ্যমে JSON mappings সঠিকভাবে কাজ করবে।
Content added || updated By

Custom Exception Handling Strategies

235

Jackson JSON প্রক্রিয়াকরণের সময় কিছু ক্ষেত্রে Exception ঘটতে পারে, যেমন invalid data format, missing required fields, বা unsupported types। এই ধরনের exceptions হ্যান্ডেল করার জন্য আপনি Jackson এর Custom Exception Handling Strategies ব্যবহার করতে পারেন। Jackson এ Custom Exception Handling করতে Jackson-এর কিছু কাস্টম DeserializationException এবং SerializationException হ্যান্ডলিং কৌশল রয়েছে, যা নির্দিষ্ট ভুলগুলির জন্য কাস্টম এক্সপ্লানেশন প্রদান করে।

Jackson Exception Handling Overview

Jackson সাধারণত JSON Serialization এবং Deserialization এর সময় কিছু নির্দিষ্ট exceptions ছুঁড়ে দেয়, যেগুলি ডিফল্টভাবে JsonProcessingException এ ক্যাচ করা হয়। তবে, আপনি এই exceptions কে কাস্টমাইজ করতে পারেন, যাতে আপনার অ্যাপ্লিকেশন আরও পরিস্কারভাবে এবং ইউজার-ফ্রেন্ডলি মেসেজ প্রদান করতে পারে।


Common Jackson Exceptions

  1. JsonMappingException:
    • যখন JSON ডেটা Java অবজেক্টের সাথে সঠিকভাবে ম্যাপ হতে পারে না (যেমন, অবৈধ ডেটা টাইপ বা মিসিং ফিল্ড)।
  2. JsonParseException:
    • যখন JSON পার্স করার সময় সিনট্যাক্স ভুল থাকে (যেমন, অবৈধ JSON ফরম্যাট)।
  3. InvalidFormatException:
    • যখন JSON ডেটার ফরম্যাট Java অবজেক্টের জন্য উপযুক্ত নয় (যেমন, টাইপ কাস্টিং সমস্যা)।
  4. JsonProcessingException:
    • একটি অভ্যন্তরীণ superclass যা সাধারণভাবে Jackson এ JSON পার্সিং এবং প্রক্রিয়াকরণের সময় অন্য যেকোনো exception ধরে।

Custom Exception Handling Strategies

1. Custom Deserialization Exception Handling

কাস্টম Deserialization exception হ্যান্ডলিং এর জন্য, আপনি @JsonDeserialize অ্যানোটেশন ব্যবহার করতে পারেন এবং Custom Deserializer তৈরি করে বিশেষভাবে invalid data অথবা missing required fields এর জন্য কাস্টম exception বা error মেসেজ তৈরি করতে পারেন।

Custom Deserializer উদাহরণ:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;

import java.io.IOException;

public class CustomDateDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String date = p.getText();
        try {
            // Custom logic to parse the date
            if (date.length() != 10) { // Invalid date format
                throw new InvalidFormatException(p, "Invalid date format, expected YYYY-MM-DD", date, String.class);
            }
            return date;
        } catch (Exception e) {
            throw new InvalidFormatException(p, "Invalid date format", date, String.class);
        }
    }
}
Person ক্লাসে Custom Deserializer প্রয়োগ করা:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class Person {
    private String name;

    @JsonDeserialize(using = CustomDateDeserializer.class)
    private String birthDate;

    // Constructors, Getters, Setters
}
Error Handling Example:
import com.fasterxml.jackson.databind.ObjectMapper;

public class CustomDeserializerExample {
    public static void main(String[] args) {
        String json = "{\"name\":\"Rahim\",\"birthDate\":\"12-2020-01\"}";  // Invalid date format

        try {
            ObjectMapper mapper = new ObjectMapper();
            Person person = mapper.readValue(json, Person.class);
            System.out.println(person.getName());
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}
Output:
Error: Invalid date format, expected YYYY-MM-DD

এই উদাহরণে, যখন invalid date format পাওয়া যায়, তখন InvalidFormatException Exception সহ কাস্টম error মেসেজ পাঠানো হয়।


2. Custom Serialization Exception Handling

Serialization এর সময় যখন কোনো অবজেক্ট JSON এ রূপান্তর করার সময় সমস্যা হয় (যেমন, unsupported type বা invalid field), তখন Custom Serializer ব্যবহার করে কাস্টম exception হ্যান্ডলিং করা যায়।

Custom Serializer উদাহরণ:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;

import java.io.IOException;

public class CustomPriceSerializer extends JsonSerializer<Double> {

    @Override
    public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        try {
            if (value < 0) {
                throw new InvalidFormatException(gen, "Price cannot be negative", value, Double.class);
            }
            gen.writeNumber(value);
        } catch (Exception e) {
            throw new InvalidFormatException(gen, "Invalid price format", value, Double.class);
        }
    }
}
Product ক্লাসে Custom Serializer প্রয়োগ করা:
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class Product {
    private String name;

    @JsonSerialize(using = CustomPriceSerializer.class)
    private double price;

    // Constructors, Getters, Setters
}
Error Handling Example:
import com.fasterxml.jackson.databind.ObjectMapper;

public class CustomSerializerExample {
    public static void main(String[] args) {
        Product product = new Product("Laptop", -999.99);  // Invalid price

        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String json = objectMapper.writeValueAsString(product);
            System.out.println(json);
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}
Output:
Error: Invalid price format

এখানে, যদি পণ্যের মূল্য নেতিবাচক (negative) হয়, তবে InvalidFormatException Exception সহ একটি কাস্টম error মেসেজ পাঠানো হয়েছে।


3. Global Exception Handling Strategy in Spring Boot (if using Spring)

Spring Boot-এ Jackson এর কাস্টম exception হ্যান্ডলিংয়ের জন্য একটি গ্লোবাল exception handler ব্যবহার করা যেতে পারে। এখানে Spring Boot এর @ControllerAdvice ব্যবহার করে কাস্টম exception হ্যান্ডলিং করা হয়।

Global Exception Handler Example:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleAllExceptions(Exception ex) {
        return new ResponseEntity<>("Custom Error: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(InvalidFormatException.class)
    public ResponseEntity<String> handleInvalidFormatException(InvalidFormatException ex) {
        return new ResponseEntity<>("Custom Error: Invalid format - " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }
}
Controller Example:
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;

@RestController
public class ProductController {

    @GetMapping("/product")
    public Product getProduct() {
        return new Product("Laptop", -500); // Invalid price will trigger exception
    }
}

Summary of Custom Exception Handling Strategies

Exception TypeUse CaseSolution Approach
InvalidFormatExceptionInvalid date format, number format issuesUse JsonDeserializer or JsonSerializer with custom logic.
JsonMappingExceptionObject field mapping issues, mismatched typesCustom Exception in Deserializer/Serializer
JsonParseExceptionSyntax error in JSON data (unexpected tokens, illegal characters)Handle with JsonParseException and throw customized message
Custom Exception HandlingValidation issues like negative price, missing required fieldImplement @JsonSerialize, @JsonDeserialize, or use global handler in Spring Boot

  1. Custom Exception Handling Jackson এর মাধ্যমে ডেটা প্রক্রিয়া করার সময় সঠিক error মেসেজ তৈরি করতে সহায়তা করে।
  2. Deserialization এবং Serialization এ কাস্টম Exception হ্যান্ডলিং নিশ্চিত করে যে ডেটা সঠিকভাবে প্রক্রিয়া হবে এবং ইউজার ফ্রেন্ডলি মেসেজ দেওয়া হবে।
  3. Jackson exception handling কাস্টমাইজেশন আপনাকে ডেটা ভ্যালিডেশন এবং পার্সিং-এর ক্ষেত্রে অধিক নিয়ন্ত্রণ প্রদান করে।
Content added || updated By

Debugging Techniques এবং Best Practices

281

Jackson ব্যবহার করে JSON Serialization এবং Deserialization করতে গিয়ে অনেক সময় বিভিন্ন ধরনের সমস্যা এবং এরর দেখা দিতে পারে। সঠিক debugging techniques এবং best practices জানা থাকলে আপনি দ্রুত সমস্যার সমাধান করতে পারেন এবং আপনার কোডটিকে আরও কার্যকর এবং নিরাপদভাবে পরিচালনা করতে পারবেন।


Jackson-এ Debugging Techniques

Jackson এর সাথে কাজ করার সময় debugging প্রক্রিয়া কিছুটা জটিল হতে পারে, কারণ JSON এবং Java Object-এর মধ্যে মানচিত্রের সমস্যা বা টাইপ কনভার্সন সমস্যাগুলি মাঝে মাঝে ক্লিয়ারভাবে উঠে আসে না। নিচে কিছু debugging techniques দেওয়া হলো যা Jackson ব্যবহার করার সময় কাজে আসবে।

1. ObjectMapper ব্যবহার করে লগিং করা

Jackson এর ObjectMapper ক্লাস একটি অত্যন্ত কার্যকরী টুল যা JSON-এ রূপান্তরিত/ডেসিরিয়ালাইজড অবজেক্ট সম্পর্কে লগ দিতে পারে। আপনি লগে JSON ডেটা বা সম্ভাব্য ত্রুটি দেখতে পারেন।

import com.fasterxml.jackson.databind.ObjectMapper;

public class DebuggingExample {
    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            String jsonString = "{\"name\": \"John\", \"age\": 30}";
            // Log JSON string and serialized object
            Person person = objectMapper.readValue(jsonString, Person.class);
            System.out.println("Deserialized Object: " + person);
        } catch (Exception e) {
            // Log the error
            System.err.println("Error: " + e.getMessage());
        }
    }
}

2. Detailed Exception Messages

Jackson দ্বারা ডেসিরিয়ালাইজেশন বা সিরিয়ালাইজেশন এর সময় যদি কোনো ভুল হয়, যেমন invalid format বা missing fields, তাহলে exception messages পড়া খুবই গুরুত্বপূর্ণ। Jackson সাধারণত ব্যতিক্রমের মাধ্যমে সমস্যা জানায়, এবং এটির stack trace তে আপনি ভুলের ধরন সম্পর্কে বিস্তারিত তথ্য পাবেন।

3. @JsonFormat ব্যবহার করে Custom Formats

Jackson এর @JsonFormat অ্যানোটেশন ব্যবহার করে আপনি বিভিন্ন ডেটা টাইপের জন্য কাস্টম ফরম্যাট নির্ধারণ করতে পারেন, যেমন তারিখ এবং সময় ফরম্যাট। এর মাধ্যমে আপনি Debugging এর সময় যে কোন অবাঞ্ছিত formatting issues এড়াতে পারবেন।

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

public class Event {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date eventDate;
    
    // Getter and Setter
}

4. @JsonProperty এবং @JsonIgnore

JSON ফিল্ডগুলোর নাম যদি Java ফিল্ডের সাথে না মেলে, তাহলে @JsonProperty ব্যবহার করতে পারেন। একইভাবে, যদি কোন ফিল্ড Serializing বা Deserializing করতে না চান, তবে @JsonIgnore ব্যবহার করা যায়। এর মাধ্যমে property mismatch বা missing field সমস্যা কমানো যায়।

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {
    @JsonProperty("user_name")
    private String name;

    @JsonIgnore
    private String password;

    // Getters and Setters
}

Jackson Best Practices

Jackson ব্যবহার করার সময় কিছু best practices মেনে চললে আপনি কোডটি আরও পরিষ্কার, নিরাপদ এবং দক্ষভাবে পরিচালনা করতে পারবেন। এখানে কিছু best practices দেওয়া হলো যা Jackson এর ব্যবহারে আপনাকে সাহায্য করবে।

1. ObjectMapper পুনরায় ব্যবহার করুন

Jackson এর ObjectMapper ক্লাস ভারী একটি অবজেক্ট এবং এটি বারবার তৈরি করলে পারফরম্যান্সে প্রভাব ফেলতে পারে। তাই ObjectMapper কে একটি Singleton হিসেবে ব্যবহার করা উচিত।

public class ObjectMapperProvider {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static ObjectMapper getInstance() {
        return OBJECT_MAPPER;
    }
}

2. @JsonProperty এবং @JsonInclude ব্যবহার করুন

Jackson অ্যানোটেশন ব্যবহার করে null ফিল্ডগুলো বাদ দিতে পারেন। @JsonInclude(JsonInclude.Include.NON_NULL) ব্যবহার করলে শুধুমাত্র null নয় এমন ফিল্ডগুলো JSON-এ সিরিয়ালাইজ হবে। এছাড়া, @JsonProperty ফিল্ডগুলোর নাম কাস্টমাইজ করতে সহায়তা করে।

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
    @JsonProperty("user_id")
    private int id;

    private String name;

    private String address;
}

3. Exception Handling এবং Validation

Jackson ব্যবহার করার সময় DeserializationException বা SerializationException ঘটতে পারে, বিশেষত যদি JSON ফর্ম্যাট সঠিক না থাকে বা টাইপ মিসম্যাচ থাকে। আপনি try-catch block ব্যবহার করে এই ত্রুটিগুলো ধরতে পারেন এবং ইউজারকে পরিষ্কার এরর মেসেজ দিতে পারেন।

try {
    ObjectMapper objectMapper = new ObjectMapper();
    Person person = objectMapper.readValue(jsonString, Person.class);
} catch (JsonProcessingException e) {
    System.err.println("Error during JSON processing: " + e.getMessage());
}

4. Use @JsonView for Fine-Grained Control

@JsonView ব্যবহার করে আপনি Serialization/Deserialization এর সময় কেবলমাত্র নির্দিষ্ট প্রপার্টি সিরিয়ালাইজ বা ডেসিরিয়ালাইজ করতে পারেন। এটি আপনার অ্যাপ্লিকেশনে ভিউ ভিত্তিক কন্ট্রোল যোগ করতে সাহায্য করে।

import com.fasterxml.jackson.annotation.JsonView;

public class User {
    @JsonView(Views.Public.class)
    private String name;

    @JsonView(Views.Internal.class)
    private String password;

    // Getters and Setters
}

5. Avoid Circular References

Jackson ব্যবহার করার সময় Circular references (যেমন Parent -> Child -> Parent) সমস্যা তৈরি করতে পারে। @JsonManagedReference এবং @JsonBackReference অ্যানোটেশন ব্যবহার করে Circular references সমাধান করা যায়। অথবা, @JsonIdentityInfo ব্যবহার করে Object ID এর মাধ্যমে circular reference এড়ানো যেতে পারে।

import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.fasterxml.jackson.annotation.JsonBackReference;

public class Parent {
    @JsonManagedReference
    private Child child;
}

public class Child {
    @JsonBackReference
    private Parent parent;
}

6. Customize Date/Time Formats with @JsonFormat

Jackson-এ Date/Time ডেটা সিরিয়ালাইজ এবং ডেসিরিয়ালাইজ করার সময় @JsonFormat অ্যানোটেশন ব্যবহার করতে পারেন, যা ডেটার আউটপুট ফরম্যাট কাস্টমাইজ করে। এর মাধ্যমে আপনি সহজেই ডেটার কাস্টম ফরম্যাট নির্ধারণ করতে পারেন।

import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

public class Event {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date eventDate;
    
    // Getter and Setter
}

7. Enable Pretty Printing for Debugging

ডিবাগging বা JSON আউটপুট পরিষ্কারভাবে দেখতে Jackson এ pretty printing সক্ষম করতে পারেন, যা JSON আউটপুটকে আরও পড়তে সহজ করে তোলে।

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

String json = objectMapper.writeValueAsString(person);
System.out.println(json);

8. Use Jackson Mix-ins for Third-party Classes

যদি আপনি কোনো third-party class ব্যবহার করেন এবং সেই ক্লাসের কিছু ফিল্ড কাস্টমাইজ করতে চান, তবে Mix-in ব্যবহার করতে পারেন। Mix-in Annotations দিয়ে আপনি third-party ক্লাসের জন্য Jackson কনফিগারেশন অ্যাড করতে পারেন।

public abstract class PersonMixin {
    @JsonProperty("full_name")
    abstract String getName();
}

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Person.class, PersonMixin.class);

Jackson ব্যবহার করার সময় কিছু debugging techniques এবং best practices অনুসরণ করলে আপনি JSON সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন প্রক্রিয়াটি আরও কার্যকরী এবং স্থিতিশীল রাখতে পারবেন:

  1. ObjectMapper পুনঃব্যবহার: একবার তৈরি করা ObjectMapper কে পুনঃব্যবহার করুন পারফরম্যান্স উন্নতির জন্য।
  2. @JsonProperty, @JsonInclude, @JsonAutoDetect: এগুলির মাধ্যমে ফিল্ডের visibility এবং serialization কাস্টমাইজ করুন।
  3. @JsonView এবং @JsonFormat: JSON ফরম্যাট এবং ভিউ নিয়ন্ত্রণ করুন।
  4. Exception Handling: Jackson ত্রুটিগুলো সঠিকভাবে হ্যান্ডল করুন এবং পরিষ্কার মেসেজ দিন।
  5. Circular Reference Handling: @JsonManagedReference, @JsonBackReference, এবং @JsonIdentityInfo ব্যবহার করে Circular reference সমস্যা এড়ান।

এই best practices আপনাকে Jackson এর ব্যবহারে সাহায্য করবে, যাতে আপনার কোডটি আরও পরিষ্কার, কার্যকর, এবং মেমরি ব্যবহারে দক্ষ হয়।

Content added || updated By
Promotion

Are you sure to start over?

Loading...