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 হলো:
JsonParseException:- এটি সাধারণত তখন ঘটে যখন JSON স্ট্রিংটি সঠিকভাবে ফর্ম্যাট করা হয় না (যেমন: ভুল সিঙ্গল কোটেশন, অনুপস্থিত ক্লোজিং ব্রেসেস ইত্যাদি)।
JsonMappingException:- এটি তখন ঘটে যখন Jackson একটি JSON ডেটাকে নির্দিষ্ট Java অবজেক্টে ম্যাপ করতে ব্যর্থ হয় (যেমন: ফিল্ডের টাইপের মিল না হওয়া)।
JsonProcessingException:- এটি সাধারণ superclass যা অন্য সকল exception class গুলোকে একত্রিত করে।
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
@JsonIgnoreProperties(ignoreUnknown = true):- আপনি যদি চান যে JSON ডেটার অজানা ফিল্ডগুলো উপেক্ষা করা হোক, তাহলে
@JsonIgnorePropertiesব্যবহার করুন। এটি ডেসিরিয়ালাইজেশনের সময় অজানা প্রপার্টি উপেক্ষা করবে।
- আপনি যদি চান যে JSON ডেটার অজানা ফিল্ডগুলো উপেক্ষা করা হোক, তাহলে
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class User {
private String name;
private int age;
// Getters and Setters
}
- Global ObjectMapper Configuration:
- আপনি
ObjectMapperএর মাধ্যমে গ্লোবাল কনফিগারেশন তৈরি করতে পারেন, যাতে ডেসিরিয়ালাইজেশন সময় অজানা প্রপার্টি উপেক্ষা করা হয়।
- আপনি
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- 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 গুলো কার্যকরভাবে হ্যান্ডেল করতে পারেন।
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 ইত্যাদি থেকে তৈরি হয়।
উপসংহার
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
সমাধান:
@JsonIgnorePropertiesব্যবহার করে অজানা প্রোপার্টি উপেক্ষা করুন।- এটি
ignoreUnknownঅপশন দিয়ে আপনি JSON থেকে অজানা প্রোপার্টি সঠিকভাবে বাদ দিতে পারেন।
- এটি
@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
সমাধান:
- JSON ফরম্যাট ঠিক করা: JSON ফিল্ডটি সঠিক ডেটা টাইপে রূপান্তর করুন।
@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?)
সমাধান:
- Default Constructor নিশ্চিত করুন।
- Getter এবং Setter Method নিশ্চিত করুন।
@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
সমাধান:
@JsonIncludeব্যবহার করেnullফিল্ডে default behavior নির্ধারণ করা।@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
সমাধান:
@JsonManagedReferenceএবং@JsonBackReferenceব্যবহার করে circular references এড়ানো।@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এবং@JsonBackReferencecircular references ব্লক করতে সাহায্য করে।- Default constructors এবং getter/setter methods নিশ্চিত করার মাধ্যমে JSON mappings সঠিকভাবে কাজ করবে।
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
JsonMappingException:- যখন JSON ডেটা Java অবজেক্টের সাথে সঠিকভাবে ম্যাপ হতে পারে না (যেমন, অবৈধ ডেটা টাইপ বা মিসিং ফিল্ড)।
JsonParseException:- যখন JSON পার্স করার সময় সিনট্যাক্স ভুল থাকে (যেমন, অবৈধ JSON ফরম্যাট)।
InvalidFormatException:- যখন JSON ডেটার ফরম্যাট Java অবজেক্টের জন্য উপযুক্ত নয় (যেমন, টাইপ কাস্টিং সমস্যা)।
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 Type | Use Case | Solution Approach |
|---|---|---|
| InvalidFormatException | Invalid date format, number format issues | Use JsonDeserializer or JsonSerializer with custom logic. |
| JsonMappingException | Object field mapping issues, mismatched types | Custom Exception in Deserializer/Serializer |
| JsonParseException | Syntax error in JSON data (unexpected tokens, illegal characters) | Handle with JsonParseException and throw customized message |
| Custom Exception Handling | Validation issues like negative price, missing required field | Implement @JsonSerialize, @JsonDeserialize, or use global handler in Spring Boot |
- Custom Exception Handling Jackson এর মাধ্যমে ডেটা প্রক্রিয়া করার সময় সঠিক error মেসেজ তৈরি করতে সহায়তা করে।
- Deserialization এবং Serialization এ কাস্টম Exception হ্যান্ডলিং নিশ্চিত করে যে ডেটা সঠিকভাবে প্রক্রিয়া হবে এবং ইউজার ফ্রেন্ডলি মেসেজ দেওয়া হবে।
- Jackson exception handling কাস্টমাইজেশন আপনাকে ডেটা ভ্যালিডেশন এবং পার্সিং-এর ক্ষেত্রে অধিক নিয়ন্ত্রণ প্রদান করে।
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 সিরিয়ালাইজেশন এবং ডেসিরিয়ালাইজেশন প্রক্রিয়াটি আরও কার্যকরী এবং স্থিতিশীল রাখতে পারবেন:
ObjectMapperপুনঃব্যবহার: একবার তৈরি করাObjectMapperকে পুনঃব্যবহার করুন পারফরম্যান্স উন্নতির জন্য।@JsonProperty,@JsonInclude,@JsonAutoDetect: এগুলির মাধ্যমে ফিল্ডের visibility এবং serialization কাস্টমাইজ করুন।@JsonViewএবং@JsonFormat: JSON ফরম্যাট এবং ভিউ নিয়ন্ত্রণ করুন।- Exception Handling: Jackson ত্রুটিগুলো সঠিকভাবে হ্যান্ডল করুন এবং পরিষ্কার মেসেজ দিন।
- Circular Reference Handling:
@JsonManagedReference,@JsonBackReference, এবং@JsonIdentityInfoব্যবহার করে Circular reference সমস্যা এড়ান।
এই best practices আপনাকে Jackson এর ব্যবহারে সাহায্য করবে, যাতে আপনার কোডটি আরও পরিষ্কার, কার্যকর, এবং মেমরি ব্যবহারে দক্ষ হয়।
Read more