Serializable
Işimi başdan geçirdim, tutuş prosesiň awtomatiki ýerine ýetirilmegi begenip bilmeýär. Sereden mysallarymyz hem çylşyrymly däldi. Ylalaşyk näme? Näme üçin aslynda şol bir mesele üçin başga bir interfeýs? Hakykat, Serializable
onuň birnäçe kemçilikleri bar. Olaryň käbirini sanap geçeliň:
-
Çykyş. Interfeýsiň
Serializable
köp artykmaçlygy bar, ýöne ýokary öndürijilik olaryň biri däl.
Birinjiden , içerki mehanizm Serializable
köp mukdarda hyzmat maglumatlary we iş wagtynda dürli wagtlaýyn maglumatlary döredýär.
Ikinjiden (bu meselä indi girip, boş wagtyňyz okamaly dälsiňiz), iş Serializable
Reflection API ulanmaga esaslanýar. Bu gapma-garşylyk size Java-da mümkin däl ýaly zatlary etmäge mümkinçilik berýär: mysal üçin, hususy meýdanlaryň bahalaryny üýtgediň. JavaRush-da Reflection API hakda ajaýyp makala bar , bu hakda şu ýerden okap bilersiňiz.
-
Çeýeligi. Ulanylanda serializasiýa-deserializasiýa prosesine asla gözegçilik etmeýäris
Serializable
.Bir tarapdan, bu gaty amatly, sebäbi hakykatdanam öndürijilik bilen gyzyklanmasak, kod ýazmazlyk amatly ýaly görünýär. Reallyöne seriallaşdyrma logikasyna hakykatdanam käbir aýratynlyklarymyzy (olaryň biriniň mysaly aşakda bolar) goşmaly bolsa näme etmeli?
Aslynda, prosese gözegçilik etmeli zatlarymyz,
transient
käbir maglumatlary aýyrmak üçin açar söz we hut şu. “Gurallar toplumy” ýaly tertipläň: / -
Howpsuzlyk. Bu nokat öňküsinden bölekleýin gelýär.
Bu barada öň kän pikir etmedik, ýöne synpyňyzdaky käbir maglumatlar “beýleki adamlaryň gulaklary” (has takygy, gözler) üçin niýetlenmedik bolsa näme etmeli? Simpleönekeý mysal, häzirki dünýäde bir topar kanunlar bilen düzgünleşdirilýän ulanyjynyň paroly ýa-da beýleki şahsy maglumatlary.
Ulanylanda
Serializable
, aslynda bu hakda hiç zat edip bilmeris. Hemme zady bolşy ýaly seriallaşdyrýarys., Öne, gowy görnüşde, faýla ýazmazdan ýa-da tora geçirmezden ozal şular ýaly maglumatlary şifrlemeli. Emma
Serializable
bu mümkinçilik bermeýär.
Externalizable
.
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class UserInfo implements Externalizable {
private String firstName;
private String lastName;
private String superSecretInformation;
private static final long SERIAL_VERSION_UID = 1L;
//...конструктор, геттеры, сеттеры, toString()...
@Override
public void writeExternal(ObjectOutput out) throws IOException {
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
}
Görşüňiz ýaly, möhüm üýtgeşmeler etdik! Esasy biri düşnüklidir: interfeýs ýerine ýetirilende Externalizable
iki hökmany usuly ulanmaly - writeExternal()
we readExternal()
. Öň hem aýdyşymyz ýaly seriallaşdyrmak we deserializasiýa üçin ähli jogapkärçilik programmistiň üstüne düşer. Şeýle-de bolsa, indi bu prosese gözegçilik etmezlik meselesini çözüp bilersiňiz! Tutuş proses gönüden-göni siz tarapyndan programmirlendi, bu, elbetde has çeýe mehanizmi döredýär. Mundan başga-da, howpsuzlyk meselesi hem çözülýär. Görşüňiz ýaly, synpymyzda bir meýdan bar: şifrlenen saklanyp bilinmeýän şahsy maglumatlar. Indi bu çäklendirmä laýyk gelýän kody aňsatlyk bilen ýazyp bileris. Mysal üçin, gizlin maglumatlary şifrlemek we şifrlemek üçin synpymyza iki sany ýönekeý hususy usul goşuň. Olary bir faýla ýazarys we faýldan kodlanan görnüşde okarys. Galan maglumatlary bolsa bolşy ýaly ýazarys we okarys :) Netijede synpymyz şuňa meňzeş bir zat görüner:
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.Base64;
public class UserInfo implements Externalizable {
private String firstName;
private String lastName;
private String superSecretInformation;
private static final long serialVersionUID = 1L;
public UserInfo() {
}
public UserInfo(String firstName, String lastName, String superSecretInformation) {
this.firstName = firstName;
this.lastName = lastName;
this.superSecretInformation = superSecretInformation;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(this.getFirstName());
out.writeObject(this.getLastName());
out.writeObject(this.encryptString(this.getSuperSecretInformation()));
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
firstName = (String) in.readObject();
lastName = (String) in.readObject();
superSecretInformation = this.decryptString((String) in.readObject());
}
private String encryptString(String data) {
String encryptedData = Base64.getEncoder().encodeToString(data.getBytes());
System.out.println(encryptedData);
return encryptedData;
}
private String decryptString(String data) {
String decrypted = new String(Base64.getDecoder().decode(data));
System.out.println(decrypted);
return decrypted;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public String getSuperSecretInformation() {
return superSecretInformation;
}
}
Leksiýada eýýäm duş gelen parametrler bilen birmeňzeş ObjectOutput out
we parametrleri ulanýan iki usuly durmuşa geçirdik . Dogry wagtda zerur maglumatlary şifrleýäris ýa-da şifrleýäris we bu görnüşde obýektimizi seriallaşdyrmak üçin ulanýarys. Munuň iş ýüzünde nähili boljakdygyny göreliň: ObjectInput
Serializable
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\save.ser");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
UserInfo userInfo = new UserInfo("Ivan", "Ivanov", "Ivan Ivanov's passport data");
objectOutputStream.writeObject(userInfo);
objectOutputStream.close();
}
}
Usullarda encryptString()
we usullarda decryptString()
gizlin maglumatlaryň haýsy görnüşde ýazyljakdygyny we okaljakdygyny barlamak üçin konsola çykyş goşduk. Aboveokardaky kod konsola aşakdaky setiri çykarýar: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh Şifrlemek şowly boldy! Faýlyň doly mazmuny şuňa meňzeýär: ¬n sr UserInfoG!
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
UserInfo userInfo = (UserInfo) objectInputStream.readObject();
System.out.println(userInfo);
objectInputStream.close();
}
}
Dogrusy, bu ýerde çylşyrymly zat ýok ýaly, işlemeli! Işledeliň ... "esasy" sapakdaky kadadan çykma java.io.InvalidClassException: UserInfo; dogry konstruktor ýok Oops :( Bu gaty ýönekeý däldi! Deserializasiýa mehanizmi kadadan çykma etdi we deslapky konstruktor döretmegimizi talap etdi. Näme üçin? Serializable
Biz onsuz dolandyrdyk ...: / Ine, başga bir möhüm meselä gelýäris Serializable
Arasyndaky tapawut Externalizable
diňe bir programmist üçin “giňeldilen” girişde we prosesi has çeýe dolandyrmak ukybynda däl, eýsem prosesiň özünde-de bar. Ilki bilen deserializasiýa mehanizminde ... Ulanylanda Serializable
ýat ýönekeý bolýar obýekt üçin bölünip berilýär, şondan soň ähli meýdanlaryny doldurýan akymdan bahalar okalýar. Eger ulansak Serializable
, obýekt konstruktory çagyrylmaýar! workhli işler şöhlelendirme arkaly amala aşyrylýar (Soňky döwürde gysgaça belläp geçen Reflection API) leksiýa). Şeýle ýagdaýda Externalizable
deserializasiýa mehanizmi başgaça bolar. Ilki başda deslapky konstruktor diýilýär. Diňe şondan soň obýektiň meýdanlaryny doldurmak üçin UserInfo
döredilen döredilen obýekt usuly çagyrylýar . readExternal()
näme üçin interfeýsi amala aşyrýan islendik synpda Externalizable
deslapky konstruktor bolmaly . Geliň, synpymyza goşalyň UserInfo
we kody täzeden işledeliň:
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\save.ser");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
UserInfo userInfo = (UserInfo) objectInputStream.readObject();
System.out.println(userInfo);
objectInputStream.close();
}
}
Konsol çykyşy: Iwan Iwanowyň pasport maglumatlary UserInfo {firstName = 'Iwan', lastName = 'Iwanow', superSecretInformation = 'Iwan Iwanowyň pasport maglumatlary'} düýbünden başga mesele! Ilki bilen gizlin maglumatlar bilen şifrlenen setir konsola çykdy, soňra obýektimiz faýldan sim görnüşinde dikeldildi! Thehli meseleleri şeýdip üstünlikli çözdük :) Serializasiýa we deserializasiýa mowzugy ýönekeý ýaly görünýär, ýöne görşüňiz ýaly leksiýalarymyz uzyn boldy. Bularyň hemmesi däl! Bu interfeýsleriň hersini ulananyňyzda başga-da köp inçelikler bar, ýöne indi beýniňiz täze maglumatlaryň göwrüminden ýarylmaz ýaly, has möhüm nokatlary gysgaça sanap geçerin we goşmaça okamaga baglanyşyk bererin. Onda başga näme bilmeli? Ilki bilen , seriallaşdyrylanda (ulanmagyňyz Serializable
ýa-da tapawudyňyz ýok Externalizable
) üýtgeýänlere üns beriň static
. Ulanylanda Serializable
bu meýdanlar asla seriýalaşdyrylmaýar (we şoňa görä-de olaryň bahasy üýtgemeýär, sebäbi static
meýdanlar obýekt däl-de, klasa degişlidir). Itöne ony ulananyňyzda Externalizable
prosese özüňiz gözegçilik edýärsiňiz, şonuň üçin tehniki taýdan bu edilip bilner. Itöne maslahat berilmeýär, sebäbi bu inçe ýalňyşlyklar bilen doldurylýar. Ikinjiden , üýtgediji bilen üýtgeýänlere hem üns berilmelidir final
. Ulanylanda, Serializable
adatdakysy ýaly seriallaşdyrylýar we deserializasiýa edilýär, ýöne ulanylanda üýtgeýjini Externalizable
deserializasiýa etmekfinal
mümkin däl ! Sebäbi ýönekeý: ähli final
meýdançalar deslapky konstruktor çagyrylanda başlaýar we şondan soň olaryň bahasy üýtgedilip bilinmez. Şol sebäpden, meýdanlary öz içine alýan obýektleri seriallaşdyrmak üçin final
, adaty seriallaşdyrma ulanyň Serializable
. Üçünjiden , miras ulanylanda, käbir Externalizable
synpdan gelýän miras synplarynyň hemmesinde deslapky konstruktorlar bolmaly. Ynha, seriallaşdyrma mehanizmleri barada gowy makalalara käbir baglanyşyklar:
Görüşýänçäk! :)
GO TO FULL VERSION