|
Java Dilinde Serialization (Serileştirme) İşlemleri - 2 |
|
Gönderiliyor lütfen bekleyin... |
|
|
Java’da nesne serileştirme işlemleri ile ilgili bu ikinci makalemde serileştirme ile ilgili birkaç özellikten bahsetmek istiyorum. İlk makalede basit bir serialization ve deserialization işleminin nasıl yapılacağını anlatmıştık. Bazen serileştirme yaparken nesnenizin bazı bölümlerinin serileştirilmesini istemeyebilirsiniz ya da nesnenizin üzerindeki başka bir alt nesneyi serileştirmek istemeyebilirsiniz. Yani serileştirme işlemi üzerinde daha fazla kontrol sahibi olmak isteyebilirsiniz. Bu durumda Serialization ara yüzü (interface) yerine Externalizable ara yüzünü kullanmak daha uygun olur.
Externalizable
Bu arayüzü kullanarak serileştirme işlemi üzerinde daha spesifik işlemler gerçekleştirebiliriz. Externalizable ara yüzünün serialization ve deserialization işlemleri sırasında kullanılan iki metodu vardır. Bunlar writeExternal() ve readExternal() metodlarıdır. Bu metodlar serialization ve deserialization işlemleri sırasında otomatik olarak kullanılırlar. Eğer serialization işlemi sırasında gerçekleştirmek istediğimiz bir şey varsa bunu writeExternal() metodunun içerisine yazarız aynı şekilde deserialization işlemi sırasında gerçekleştirmek istediğimiz bir şey varsa da bunu da readExternal() metodunun içerisine yazarız. Bunu bir örnekle daha açık hale getirelim. Örneğin bir sınıfımız var ve bu sınıfta biz kullanıcı adı, kullanıcı soyadı ve kullanıcı şifresi bilgilerini tutuyoruz. Bu sınıftan oluşturduğumuz nesnemizi de serileştirerek bir şekilde uygulamamızın başka bir yerinde
kullanacağız diyelim. Şimdi bu noktada güvenlik açısından şifrenin tutulduğu alanın serileştirilmesi doğru olmaz. Çünkü herhangi
bir şekilde birisi serileştirilmiş nesnenin tutulduğu dosyayı bir text editörde açıp içindeki herşeyi okuyabilir. Yani özetle yapmak istediğimiz şu, nesnemizdeki kullanıcı adı, kullanıcı soyadı serileştirilirken kullanıcının şifresi serileştirilmeyecek. Yani nesnemiz üzerindeki alanlardan bir tanesini serileştirme işleminin dışında tutmak istiyoruz. Şimdi örnek kodu inceleyelim :
Kullanıcı bilgileri için UserData isimli bir sınıf oluşturalım. Bu sınıf Externalizable ara yüzünü gerçeklemektedir.
import java.io.* ;
public class UserData implements Externalizable
{
private String usrName,usrSurname,usrPassword;
private int usrAge;
//Default bir constructor bulunması gerekli çünkü deserialization işlemi sırasında bu constructor kullanılacak
public UserData()
{
}
public UserData(String name,String surname,String pass,int age)
{
this.usrName=name;
this.usrSurname=surname;
this.usrPassword=pass;
this.usrAge=age;
}
public String getUserName()
{
return usrName;
}
public String getUserSurname()
{
return usrSurname;
}
public String getUserPassword()
{
return usrPassword;
}
public int getUserAge()
{
return this.usrAge;
}
//Serileştirilmesini istediğimiz nesneleri kontrol edebiliyoruz
public void writeExternal(ObjectOutput out)
{
try
{
out.writeObject(this.usrName); //usrName alanı serileştiriliyor
out.writeObject(this.usrSurname); //usrSurname alanı serileştiriliyor
out.writeInt(this.usrAge);
//usrPassword alanını serileştirmek istemediğimiz için buraya yazmadık
}
catch(Exception ex)
{
System.out.println("An exception occurred during serialization!");
}
}
public void readExternal(ObjectInput in)
{
try
{
this.usrName=(String)in.readObject(); //usrName alanımızı serileştirdiğimiz nesneden geri elde ediyoruz
this.usrSurname=(String)in.readObject(); //usrSurname alanımızı serileştirdiğimiz nesneden geri elde ediyoruz
this.usrAge=in.readInt();
//Burada dikkat etmemiz gereken bir diğer nokta da deserializtion işlemini serializtion işlemi sırasında yapılan sıra ile gerçekleştirmek
//Yani ilk olarak usrName alanını serileştirdiğimiz için ilk geri elde edeceğimiz alan usrName alanıdır. Yani sıra önemli!
}
catch(Exception ex)
{
System.out.println("An exception occurred during deserialization!");
}
}
} |
Sanırım yukarıda kod içerisinde verdiğim açıklamalar yeterli olmuştur. Yani aslında yaptığımız iş serileştirilmesi istediğimiz nesneleri writeExternal() metodu içerisinde belirtmek ve serileştirmek. Deserialization sırasında da bu nesneleri readExternal() metodu içerisinden geri okumak. Yukarıda dikkat edersek usrPassword alanımızı serileştirmek istemediğimiz için writeExternal() metodu içerisinde serileştirmedik. Yani istediğimz alanları serileştirdik, istemediklerimizi serileştirmedik.
Şimdi bir uygulama ile yukarıda tanımlı sınıfımızdan bir nesne üretelim ve bildiğimiz serileştirme metodunu kullanarak serileştirelim.
import java.io.* ;
public class MClassTest
{
public static void main (String [] args)
{
try
{
UserData d;
d=new UserData("XXXXX","YYYYY","6y5tu9&3!", 22); //Güvenli bir password :)
FileOutputStream fileOut=new FileOutputStream("UserData.dat");
ObjectOutputStream out=new ObjectOutputStream(fileOut);
out.writeObject(d);
out.close();
System.out.println("Process ends...");
}
catch(Exception ex)
{
System.out.println("An exception occurred!");
ex.printStackTrace();
}
}
} |
Uygulama klasörümüze bakarsak UserData.dat isimli dosyanın oluşturulmuş olduğunu göreceğiz. Yukarıda yaptığımız şey klasik serileştirme işlemi. Bunu zaten ilk makalede anlatmıştık
Şimdi artık elimizde disk üzerinde kayıtlı serileştirilmiş bir nesnemiz var. Şimdi de bu nesnemizi geri elde edelim (deserialize). Bu arada geri elde ettiğimiz nesnemizin usrName, usrSurname, usrPassword ve usrAge alanlarının değerlerini de yazdıralım.
import java.io.*;
public class MClassTest
{
public static void main (String [] args)
{
try
{
UserData d1;
FileInputStream fileInput=new FileInputStream("UserData.dat");
ObjectInputStream in=new ObjectInputStream(fileInput);
d1=(UserData)in.readObject();
System.out.println("Name:"+d1.getUserName()+"\nSurname:"+d1.getUserSurname()+"\nPassword:"+d1.getUserPassword()+"\nAge :"+d1.getUserAge());
System.out.println("Process ends...");
}
catch(Exception ex)
{
System.out.println("An exception occurred!");
ex.printStackTrace();
}
}
}
|
Yukarıdaki kodu çalıştırdığımızda programımız bize aşağıdaki çıktıyı verecektir.
Name :XXXXX
Surname :YYYYY
Password :null
Age :22
Process ends... |
Gördüğümüz üzere serileştirmediğimiz bir alan olan usrPassword alanına null değeri atanmıştır. Diğer tüm alanlarımızın değerlerini aynı şekilde geri elde edebildik.
Externalizable ara yüzü ile birlikte gelen writeExternal() ve readExternal() metodları bize serileştirme üzerinde çok büyük kolaylıklar sağlamakta daha esnek serileştirme işlemleri oluşturabilmemize olanak vermektedir.
transient
Serileştirilmesini istemediğimiz alanların serileştirilmesini önlemenin bir diğer yolu da transient olarak bu alanları tanımlamaktır. Nesnemizde ilgili alan private olarak tanımlanmış olsa bile bu nesne serileştirildikten sonra o alan okunabilir (dosya bir text editör yardımı ile açılarak). Bu nedenle o tür bir alanımız varsa, yani kritik bir bilgi içeren bir alan o alanı serileştirmeyebiliriz. Java’da transient anahtar kelimesi ile tanımlanan alanlar serileştirilmezler. Hemen bununla ilgili bir örnek yapalım. Ben sadece yukarıdaki örneğimizi biraz daha basit şekilde değiştireceğim. Aynı sınıfımız (UserData) sadece kullanıcı adı ve password bilgilerini tutsun bu sefer ve password alanını serileştirmeyelim.
import java.io.* ;
//Dikkat edersek sınıfımız Serializable arayüzünü gerçeklemektedir
public class UserData implements Serializable
{
private String usrName;
private transient String usrPassword; //Bu alanı transient tanımlayarak serileştirilmesini önlüyoruz
public UserData(String name,String pass)
{
this.usrName=name;
this.usrPassword=pass;
}
public String getUserName()
{
return usrName;
}
public String getUserPassword()
{
return usrPassword;
}
} |
Şimdi de bu nesnemizi oluşturan ve serileştiren kodumuzu yazalım.
import java.io.*;
public class MClassTest
{
public static void main (String [] args)
{
try
{
UserData d;
d=new UserData("XXXXX","6y5tu9&3");
FileOutputStream fileOut=new FileOutputStream("UserData.dat");
ObjectOutputStream out=new ObjectOutputStream(fileOut);
out.writeObject(d);
out.close();
System.out.println("Process ends...");
}
catch(Exception ex)
{
System.out.println("An exception occurred!");
ex.printStackTrace();
}
}
} |
Artık nesnemizi oluşturduk ve serileştirdik. Şimdi de nesnemizi geri elde edelim (deserialize) ve usrPassword alanının durumunu görelim.
import java.io.*;
public class MClassTest
{
public static void main (String [] args)
{
try
{
UserData d1;
FileInputStream fileInput=new FileInputStream("UserData.dat");
ObjectInputStream in=new ObjectInputStream(fileInput);
d1=(UserData)in.readObject();
System.out.println("Name :"+d1.getUserName()+"\nPassword :"+d1.getUserPassword() );
System.out.println("Process ends...");
}
catch(Exception ex)
{
System.out.println("An exception occurred!");
ex.printStackTrace();
}
}
}
|
Bu durumda program çıktımız aşağıdaki gibi olur :
Name :XXXXX
Password :null
Process ends... |
Gördüğümüz gibi serileştirmediğimiz bir alan olan usrPassword alanı null değer almıştır.
Başka makalelerde görüşmek üzere…
Nihat KOÇYİĞİT
Makale:
Java Dilinde Serialization (Serileştirme) İşlemleri - 2 J# ve Java dili Nihat Koçyiğit
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|