এটি একটি দুর্দান্ত প্রশ্ন কারণ এটি এমন কোনও কিছুকে পৃথক করে যা সহজ হওয়া উচিত তবে বাস্তবে প্রচুর কোডের প্রয়োজন হয়।
শুরু করার জন্য, একটি বিমূর্তি লিখুন TypeAdapterFactory
যা আপনাকে বহির্গামী ডেটা সংশোধন করতে সহায়তা করে। এই উদাহরণটি জিএসন ২.২ এ একটি নতুন এপিআই getDelegateAdapter()
ব্যবহার করে যা আপনাকে গডস ডিফল্টরূপে ব্যবহার করবে এমন অ্যাডাপ্টারটি সন্ধান করতে দেয়। যদি আপনি কেবল স্ট্যান্ডার্ড আচরণটি সামলানো চান তবে প্রতিনিধি অ্যাডাপ্টারগুলি অত্যন্ত কার্যকর hand এবং সম্পূর্ণ কাস্টম ধরণের অ্যাডাপ্টারগুলির বিপরীতে, আপনি ক্ষেত্রগুলি যুক্ত এবং সরানোর সাথে সাথে তারা স্বয়ংক্রিয়ভাবে আপ টু ডেট থাকবে।
public abstract class CustomizedTypeAdapterFactory<C>
implements TypeAdapterFactory {
private final Class<C> customizedClass;
public CustomizedTypeAdapterFactory(Class<C> customizedClass) {
this.customizedClass = customizedClass;
}
@SuppressWarnings("unchecked")
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
return type.getRawType() == customizedClass
? (TypeAdapter<T>) customizeMyClassAdapter(gson, (TypeToken<C>) type)
: null;
}
private TypeAdapter<C> customizeMyClassAdapter(Gson gson, TypeToken<C> type) {
final TypeAdapter<C> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
return new TypeAdapter<C>() {
@Override public void write(JsonWriter out, C value) throws IOException {
JsonElement tree = delegate.toJsonTree(value);
beforeWrite(value, tree);
elementAdapter.write(out, tree);
}
@Override public C read(JsonReader in) throws IOException {
JsonElement tree = elementAdapter.read(in);
afterRead(tree);
return delegate.fromJsonTree(tree);
}
};
}
protected void beforeWrite(C source, JsonElement toSerialize) {
}
protected void afterRead(JsonElement deserialized) {
}
}
উপরের শ্রেণিটি একটি জেএসওএন ট্রি পেতে (ডিফল্টভাবে উপস্থাপিত JsonElement
) পেতে ডিফল্ট সিরিয়ালাইজেশন ব্যবহার করে এবং তারপরে beforeWrite()
সাব গাছটিকে সেই গাছটিকে কাস্টমাইজ করার অনুমতি দেওয়ার জন্য হুক পদ্ধতিটি কল করে । একইভাবে deserialization জন্য afterRead()
।
পরবর্তী আমরা নির্দিষ্ট MyClass
উদাহরণের জন্য এটি সাবক্লাস করি । চিত্রিত করার জন্য আমি মানচিত্রটিতে সিরিয়ালযুক্ত হয়ে গেলে 'আকার' নামে একটি সিন্থেটিক সম্পত্তি যুক্ত করব। এবং প্রতিসাম্যতার জন্য আমি এটি সরিয়ে ফেলব যখন এটি ডিজাইরিয়াল করা হবে। অনুশীলনে এটি কোনও স্বনির্ধারণ হতে পারে।
private class MyClassTypeAdapterFactory extends CustomizedTypeAdapterFactory<MyClass> {
private MyClassTypeAdapterFactory() {
super(MyClass.class);
}
@Override protected void beforeWrite(MyClass source, JsonElement toSerialize) {
JsonObject custom = toSerialize.getAsJsonObject().get("custom").getAsJsonObject();
custom.add("size", new JsonPrimitive(custom.entrySet().size()));
}
@Override protected void afterRead(JsonElement deserialized) {
JsonObject custom = deserialized.getAsJsonObject().get("custom").getAsJsonObject();
custom.remove("size");
}
}
পরিশেষে এটিকে একত্রে পছন্দসই Gson
উদাহরণ তৈরি করে নতুন টাইপ অ্যাডাপ্টার ব্যবহার করে:
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new MyClassTypeAdapterFactory())
.create();
গসনের নতুন টাইপএডাপ্টার এবং টাইপএডাপ্টারফ্যাক্টরি টাইপগুলি অত্যন্ত শক্তিশালী তবে এগুলি বিমূর্ত এবং কার্যকরভাবে ব্যবহারের জন্য অনুশীলনও গ্রহণ করে। আশা করি আপনি এই উদাহরণটি দরকারী খুঁজে পেয়েছেন!