CodeGym /Blog Jawa /Acak /Antarmuka sing bisa dieksternalisasi ing Jawa
John Squirrels
tingkat
San Francisco

Antarmuka sing bisa dieksternalisasi ing Jawa

Diterbitake ing grup
Hi! Dina iki kita bakal terus ngerteni serialisasi lan deserialisasi obyek Jawa . Ing wulangan pungkasan, kita kudu ngerti antarmuka panandha Serializable , mriksa conto panggunaane, lan uga sinau carane nggunakake tembung kunci transien kanggo ngontrol proses serialisasi. Ya, ujar manawa kita 'kontrol proses' bisa uga overstating. Kita duwe siji tembung kunci, siji pengenal versi, lan babagan iki. Proses liyane didhelikake ing Jawa, lan kita ora bisa ngakses. Mesthi, babagan penak, iki apik. Nanging programer ngirim ora mung dipandu dening comfort dhewe, tengen? :) Ana faktor liyane sing kudu sampeyan nimbang. Mulane Serializableora mung mekanisme serialisasi-deserialisasi ing Jawa. Dina iki kita bakal kenal karo antarmuka Externalizable . Nanging sadurunge miwiti sinau, sampeyan bisa uga duwe pitakonan sing cukup: kenapa kita butuh mekanisme liyane? Serializableiya proyek, lan apa ora tresna marang implementasine otomatis saka kabèh proses? Lan conto sing kita deleng uga ora rumit. Dadi apa masalahe? Napa kita butuh antarmuka liyane kanggo tugas sing padha? Kasunyatane ana Serializablesawetara kekurangan. We dhaptar sawetara saka wong-wong mau:
  1. Kinerja. Antarmuka Serializablewis akeh kaluwihan, nanging kinerja dhuwur cetha ora siji saka wong-wong mau.

    Ngenalke antarmuka Externalizable - 2

    First, Serializable 's implementasine internal ngasilake jumlah gedhe saka informasi layanan lan kabeh limo data sauntara.

    Kapindho, Serializable gumantung ing API Refleksi (sampeyan ora kudu nyilem jero babagan iki saiki; sampeyan bisa maca liyane ing wektu luang, yen sampeyan kasengsem). Iki ngidini sampeyan nindakake perkara-perkara sing katon ora mungkin ing Jawa: contone, ngganti nilai kolom pribadi. CodeGym duwe artikel sing apik babagan Reflection API . Sampeyan bisa maca babagan ana.

  2. Fleksibilitas. Kita ora ngontrol proses serialisasi-deserialisasi nalika nggunakake antarmuka Serializable.

    Siji-sijine, trep banget, amarga yen kita ora prihatin babagan kinerja, mula katon apik yen ora kudu nulis kode. Nanging apa yen kita pancene kudu nambah sawetara fitur kita dhewe (kita bakal nyedhiyani conto ing ngisor iki) kanggo logika serialization?

    Sejatine, kabeh kita kudu ngontrol proses kasebut yaiku transienttembung kunci kanggo ngilangi sawetara data. Mekaten. Iku kabeh toolbox kita :/

  3. Keamanan. Item iki asale saka bagean sadurunge.

    Kita wis ora nglampahi akeh wektu mikir bab iki sadurunge, nanging apa yen sawetara informasi ing kelas sampeyan ora dimaksudaké kanggo prying mripat lan kuping wong liya? Conto prasaja yaiku tembung sandhi utawa data pangguna pribadhi liyane, sing ing jaman saiki diatur dening pirang-pirang undang-undang.

    Yen kita nggunakake Serializable, kita ora bisa nindakake apa-apa. We serialize kabeh minangka iku.

    Nanging yen kita nindakake kanthi bener, kita kudu ngenkripsi data kaya iki sadurunge nulis menyang file utawa ngirim liwat jaringan. Nanging Serializableora nggawe iki bisa.

Ngenalke antarmuka Externalizable - 3Inggih, ayo ing pungkasan ndeleng carane kelas bakal katon yen kita nggunakake antarmuka 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;

   // ...constructor, getters, setters, toString()...

   @Override
   public void writeExternal(ObjectOutput out) throws IOException {

   }

   @Override
   public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {

   }
}
Nalika sampeyan bisa ndeleng, kita duwe owah-owahan sing signifikan! Sing utama jelas: nalika ngetrapake antarmuka Externalizable, sampeyan kudu ngetrapake rong cara sing dibutuhake: writeExternal()lanreadExternal(). Kaya sing wis dakkandhakake sadurunge, tanggung jawab kanggo serialisasi lan deserialization bakal ana ing programmer. Nanging saiki sampeyan bisa ngatasi masalah ora bisa ngontrol proses kasebut! Kabeh proses diprogram langsung dening sampeyan. Alami, iki ngidini mekanisme sing luwih fleksibel. Kajaba iku, masalah keamanan wis ditanggulangi. Kaya sing sampeyan ngerteni, kelas kita duwe lapangan data pribadhi sing ora bisa disimpen tanpa enkripsi. Saiki kita bisa kanthi gampang nulis kode sing nyukupi kendala iki. Contone, kita bisa nambah kanggo kelas kita loro cara pribadi prasaja kanggo encrypt lan decrypt data sensitif. Kita bakal nulis data menyang file lan maca saka file ing wangun ndhelik. Data liyane bakal ditulis lan diwaca kaya apa wae :) Akibate, kelas kita katon kaya iki:

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;
   }
}
Kita ngleksanakake rong cara sing nggunakake padha ObjectOutputlan ObjectInputparamèter sing wis ketemu ing pawulangan bab Serializable. Ing wektu sing tepat, kita ndhelik utawa dekripsi data sing dibutuhake, lan nggunakake data sing dienkripsi kanggo nggawe serialisasi obyek kita. Ayo ndeleng carane iki katon ing laku:

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("Paul", "Piper", "Paul Piper's passport data");

       objectOutputStream.writeObject(userInfo);

       objectOutputStream.close();

   }
}
Ing encryptString()lan decryptString()cara, kita khusus ditambahaké console output kanggo verifikasi wangun kang data rahasia bakal ditulis lan diwaca. Kode ing ndhuwur nampilake baris ing ngisor iki: SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRh Enkripsi kasil! Isi lengkap berkas katon kaya mangkene: ¬н sr UserInfoГ!}ҐџC‚ћ xpt Ivant Ivanovt $SXZhbiBJdmFub3YncyBwYXNzcG9ydCBkYXRhx Saiki ayo nyoba nggunakake logika deseralisasi.

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();

   }
}
Ya, ora ana sing rumit ing kene. Iku kudu bisa! Kita mbukak lan njaluk ... Pangecualian ing thread "utama" java.io.InvalidClassException: UserInfo; ora ana konstruktor sing bener Ngenalke antarmuka Externalizable - 4 Oops! :( Ketoke, iku ora supaya gampang! Mekanisme deserialization mbuwang pangecualian lan nuntut sing kita nggawe standar konstruktor. Aku wonder kok. Kanthi , Serializablekita entuk tanpa siji ... : / Kene kita wis ketemu nuansa penting liyane. prabédan antarane Serializablelan Externalizabledumunung ora mung ing programmer kang 'ditambahi' akses lan kemampuan kanggo luwih fleksibel ngontrol proses, nanging uga ing proses dhewe. Ndhuwur kabeh, ing mekanisme deserialization . Nalika nggunakakeSerializable, memori mung diparengake kanggo obyek, banjur nilai diwaca saka stream lan digunakake kanggo nyetel kothak obyek. Yen kita nggunakake Serializable, konstruktor obyek ora disebut! Kabeh karya kedadeyan liwat refleksi (API Refleksi, sing sedhela kasebut ing pawulangan pungkasan). Kanthi Externalizable, mekanisme deserialization beda. Konstruktor standar diarani pisanan. Mung sawise iku cara UserInfoobyek digawe readExternal()disebut. Iku tanggung jawab kanggo nyetel lapangan obyek. Pramila kelas apa wae sing ngetrapake Externalizableantarmuka kudu duwe konstruktor standar . Ayo tambahake siji menyang UserInfokelas lan mbukak kode kasebut:

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();
   }
}
Output konsol: data paspor Paul Piper UserInfo \ firstName = 'Paul', lastName = 'Piper', superSecretInformation = 'Data paspor Paul Piper' } Saiki pancen beda! Kaping pisanan, senar dekripsi kanthi informasi rahasia ditampilake ing konsol. Banjur obyek sing mbalekake saka file ditampilake minangka senar! Dadi, kita wis sukses ngrampungake kabeh masalah :) Topik serialisasi lan deseralisasi katon gampang, nanging, kaya sing sampeyan ngerteni, pelajaran kasebut wis suwe. Lan akeh liyane sing durung kita bahas! Ana isih akeh subtleties melu nalika nggunakake saben antarmuka iki. Nanging supaya otak ora njeblug saka informasi anyar sing akeh banget, aku bakal menehi dhaptar sawetara poin sing luwih penting lan menehi link menyang maca tambahan. Dadi, apa maneh sampeyan kudu ngerti? Pisanan , sajrone serialisasi (preduli saka apa sampeyan nggunakake Serializableutawa Externalizable), mbayar manungsa waé kanggo staticvariabel. Nalika sampeyan nggunakake Serializable, kolom iki ora serialized ing kabeh (lan, patut, Nilai sing ora ngganti, amarga statickolom kagungane kelas, ora obyek). Nanging nalika sampeyan nggunakakeExternalizable, sampeyan ngontrol proses kasebut dhewe, supaya kanthi teknis sampeyan bisa nggawe serial. Nanging, kita ora nyaranake, amarga tumindak kasebut bakal nggawe akeh bug sing halus. Kapindho , sampeyan uga kudu menehi perhatian marang variabel kanthi finalmodifier. Nalika sampeyan nggunakake Serializable, lagi serialized lan deserialized minangka biasanipun, nanging nalika sampeyan nggunakake Externalizable, iku mokal kanggo deserialize finalvariabel ! Alesane gampang: kabeh finallapangan diwiwiti nalika konstruktor standar diarani - sawise iku, nilai kasebut ora bisa diganti. Mulane, kanggo serialize obyek sing duwe finallapangan, nggunakake serialization standar diwenehake dening Serializable. Katelu , nalika sampeyan nggunakake warisan, kabeh kelas turunan sing marisi sawetaraExternalizablekelas uga kudu konstruktor standar. Iki link menyang artikel sing apik babagan mekanisme serialisasi: Nganti wektu sabanjure! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION