Download this Blogger Template by Clicking Here!

Ad 468 X 60

Tuesday, 31 May 2011

Widgets

Sedikit Tentang Teknologi Asynchronous JavaScript and XML (Ajax) Dengan Java Platform

Siapapun yang telah menggunakan Flickr, GMail, Google Suggest, atau Google Maps akan menyadari bahwa generasi baru aplikasi web dinamis yang muncul. Aplikasi ini terlihat dan bertindak sangat mirip dengan aplikasi desktop tradisional tanpa bergantung pada plug-in atau fitur browser khusus. aplikasi Web secara tradisional telah satu set halaman HTML yang harus reloaded untuk mengubah bagian manapun dari konten. Teknologi seperti bahasa pemrograman JavaScript dan cascading style sheets (CSS) telah jatuh tempo ke titik di mana mereka dapat digunakan secara efektif untuk membuat aplikasi web yang sangat dinamis yang akan bekerja di semua browser utama. Artikel ini akan detail beberapa teknik yang dapat Anda gunakan hari ini untuk mengaktifkan aplikasi web Anda menjadi lebih kaya dan interaktif seperti aplikasi desktop.


Memperkenalkan Teknologi Asynchronous JavaScript and XML (Ajax)
Menggunakan teknologi JavaScript, halaman HTML asynchronously dapat melakukan panggilan ke server dari mana ia dimuat dan mengambil konten yang mungkin diformat sebagai dokumen XML, konten HTML, teks biasa, atau JavaScript Object Notation (JSON). Teknologi JavaScript kemudian dapat menggunakan konten tersebut untuk memperbarui atau memodifikasi Document Object Model (DOM) dari halaman HTML. Yang Asynchronous JavaScript Istilah Teknologi dan XML ( Ajax ) telah muncul baru-baru ini untuk menggambarkan model interaksi.
Ajax bukanlah hal baru. Teknik-teknik ini telah tersedia untuk pengembang penargetan Internet Explorer pada platform Windows selama bertahun-tahun. Sampai saat ini, teknologi ini dikenal sebagai Remoting web atau remote scripting. Web developer juga telah menggunakan kombinasi plug-in, applet Java, dan frame tersembunyi untuk meniru model interaksi selama beberapa waktu. Apa yang telah berubah baru-baru ini adalah dimasukkannya dukungan untuk XMLHttpRequest objek di runtimes JavaScript dari browser mainstream. Keajaiban yang sebenarnya adalah hasil dari teknologi JavaScript XMLHttpRequest object. Walaupun objek ini tidak ditentukan dalam spesifikasi teknologi JavaScript formal, semua browser utama saat ini mendukungnya. Perbedaan halus dengan teknologi JavaScript dan mendukung CSS di kalangan generasi sekarang browser seperti Mozilla Firefox, Internet Explorer, dan Safari dapat dikelola. JavaScript perpustakaan seperti Dojo , Prototype , dan Yahoo User Interface Perpustakaan telah muncul untuk mengisi di mana browser yang tidak dikelola dan untuk menyediakan model pemrograman standar. Dojo, misalnya, mengatur aksesibilitas, internasionalisasi, dan grafis lanjutan di browser - semua yang telah duri di sisi pengadopsi awal Ajax. Lebih update yakin terjadi saat diperlukan.
Apa yang membuat klien Ajax berbasis unik adalah bahwa klien berisi logika kontrol khusus halaman tertanam sebagai teknologi JavaScript. Halaman yang berinteraksi dengan teknologi JavaScript berdasarkan kejadian seperti pemuatan dokumen, klik mouse, perubahan fokus, atau bahkan timer. interaksi Ajax memungkinkan untuk pemisahan yang jelas dari logika presentasi dari data. Sebuah halaman HTML dapat menarik potongan gigitan-ukuran yang akan ditampilkan. Ajax akan membutuhkan arsitektur server-side yang berbeda untuk mendukung model interaksi. Secara tradisional, sisi server aplikasi web telah berfokus pada menghasilkan dokumen HTML untuk setiap acara klien mengakibatkan panggilan ke server. Klien kemudian akan menyegarkan dan membuat kembali halaman HTML yang lengkap untuk setiap respon. aplikasi web Rich fokus pada klien mengambil sebuah dokumen HTML yang bertindak sebagai template atau wadah dimana untuk menyuntikkan konten, berdasarkan kejadian klien menggunakan XML data diambil dari komponen server-side.
Beberapa menggunakan untuk interaksi Ajax adalah sebagai berikut:
  • Real-time data form validasi: Formulir data seperti user ID, ​​nomor seri, kode pos, atau kupon kode-kode khusus bahkan yang memerlukan server-side validasi dapat divalidasi dalam bentuk sebelum pengguna menyerahkan formulir. Lihat Validasi Form Realtime untuk rincian.
  • Autocompletion: Sebuah bagian tertentu dari data formulir seperti alamat email, nama, atau nama kota mungkin autocompleted sebagai jenis pengguna.
  • Load on demand: Berdasarkan peristiwa klien, halaman HTML dapat mengambil data lebih banyak di latar belakang, yang memungkinkan browser untuk memuat halaman dengan lebih cepat.
  • kontrol antarmuka pengguna dan efek canggih: Kontrol seperti pohon, menu, tabel data, editor rich text, kalender, dan bar kemajuan memungkinkan untuk interaksi pengguna yang lebih baik dan interaksi dengan halaman HTML, umumnya tanpa membutuhkan pengguna untuk kembali halaman tersebut.
  • Refreshing data dan server push: HTML halaman mungkin polling data dari server untuk up-to-date data-seperti skor, harga saham, cuaca, atau-data aplikasi spesifik. Klien dapat menggunakan teknik Ajax untuk mendapatkan satu set data saat ini tanpa reload halaman penuh. Polling tidak cara yang paling efisien untuk memastikan bahwa data pada halaman yang paling lancar. Emerging teknik seperti Comet sedang dikembangkan untuk menyediakan server-side push benar melalui HTTP dengan menjaga koneksi persisten antara client dan server. Lihat entri blog di Komet menggunakan Grizzly untuk lebih lanjut tentang pengembangan push server dengan teknologi Java.
  • Partial submit: Sebuah halaman HTML bisa mengirimkan data formulir yang diperlukan tanpa memerlukan refresh halaman penuh.
  • Mashup: Sebuah halaman HTML dapat memperoleh data menggunakan sisi proxy server atau dengan termasuk skrip eksternal untuk mencampur data eksternal dengan's aplikasi atau Anda layanan data Anda. Sebagai contoh, Anda dapat mencampur isi atau data dari aplikasi pihak ketiga seperti Google Maps dengan aplikasi anda sendiri.
  • Halaman sebagai aplikasi: teknik Ajax dapat dibuat untuk membuat halaman aplikasi tunggal yang terlihat dan terasa seperti aplikasi desktop. Lihat artikel tentang penggunaan Ajax dan portlet untuk lebih lanjut tentang bagaimana Anda dapat menggunakan aplikasi portlet hari ini.
Meskipun tidak semua inklusif, daftar ini menunjukkan bahwa interaksi Ajax memungkinkan aplikasi web untuk melakukan lebih dari yang mereka lakukan di masa lalu.
Anatomi dari Interaksi Ajax
Sekarang kita telah mendiskusikan apa Ajax dan apa beberapa isu tingkat yang lebih tinggi adalah, mari kita menempatkan semua potongan dan melihat sebuah Ajax-enabled aplikasi Java.
Mari kita pertimbangkan contoh. Sebuah aplikasi web yang berisi halaman HTML statis, atau sebuah halaman HTML yang dihasilkan dalam teknologi JSP berisi bentuk HTML yang membutuhkan logika sisi server untuk memvalidasi data formulir tanpa halaman menyegarkan. A-side web komponen server ( servlet ) bernama ValidateServlet akan memberikan logika validasi. Gambar 1 menggambarkan rincian dari interaksi Ajax yang akan memberikan logika validasi.


Item berikut mewakili setup dari interaksi Ajax seperti yang ditampilkan dalam Gambar 1.
  1. Sebuah peristiwa terjadi klien.
  2. Sebuah XMLHttpRequest objek dibuat dan dikonfigurasi.
  3. The XMLHttpRequest objek membuat panggilan.
  4. Permintaan diproses oleh ValidateServlet .
  5. The ValidateServlet mengembalikan dokumen XML berisi hasilnya.
  6. The XMLHttpRequest objek menyebut callback() fungsi dan proses hasilnya.
  7. HTML DOM diperbarui.
Sekarang mari kita lihat pada setiap langkah dari interaksi Ajax lebih terinci.
1. Sebuah peristiwa terjadi klien.
fungsi teknologi JavaScript yang disebut sebagai hasil dari suatu peristiwa. Dalam hal ini, fungsi validate() dapat dipetakan ke onkeyup acara pada bentuk komponen atau link.
 <Input type = "text"
             size = "20"  
               id = "userid"
             name = "id"
          onkeyup = "memvalidasi ();">

Ini elemen form akan memanggil validate() fungsi setiap kali pengguna menekan sebuah kunci di bidang bentuk.
2. Sebuah XMLHttpRequest objek dibuat dan dikonfigurasi.
Sebuah XMLHttpRequest objek dibuat dan dikonfigurasi.
 var req;

 fungsi validasi () {
    var idField = document.getElementById ("userid");
    var url = "memvalidasi id =?" + encodeURIComponent (idField.value);
    if (typeof XMLHttpRequest! = "undefined") {
        req = new XMLHttpRequest ();
    } Else if (window.ActiveXObject) {
        req = new ActiveXObject ("Microsoft.XMLHTTP");
    }
    req.open ("GET", url, true);
    req.onreadystatechange = callback;
    req.send (null);
 }

The validate() fungsi menciptakan XMLHttpRequest objek dan memanggil fungsi buka pada objek. Fungsi terbuka memerlukan tiga argumen: metode HTTP, yang merupakan GET atau POST , URL dari sisi komponen server yang objek akan berinteraksi dengan, dan nilai boolean yang menunjukkan apakah panggilan akan dibuat asynchronous. API adalah XMLHttpRequest.open(String method, String URL, boolean asynchronous) . Jika interaksi diatur sebagai asinkron ( true sebuah fungsi callback) harus ditentukan. Fungsi callback untuk interaksi ini diatur dengan pernyataan req.onreadystatechange = callback; . Lihat bagian 6 untuk rincian lebih lanjut.
3. The XMLHttpRequest objek membuat panggilan.
Ketika pernyataan req.send(null); tercapai, panggilan akan dibuat. Dalam kasus HTTP GET , konten ini mungkin null atau dibiarkan kosong. Bila fungsi ini disebut pada XMLHttpRequest objek, panggilan ke URL yang ditetapkan selama konfigurasi objek disebut. Dalam kasus contoh ini, data yang diposting ( id ) dimasukkan sebagai parameter URL.
Gunakan HTTP GET ketika permintaan idempoten, berarti bahwa dua duplikat permintaan akan mengembalikan hasil yang sama. Bila menggunakan HTTP GET metode, panjang dari URL, termasuk parameter URL escape, dibatasi oleh beberapa browser dan by-side web server kontainer. HTTP POST metode harus digunakan bila mengirim data ke server yang akan mempengaruhi sisi aplikasi server negara. HTTP POST memerlukan Content-Type header yang akan ditetapkan pada XMLHttpRequest objek dengan menggunakan pernyataan berikut:
 req.setRequestHeader ("Content-Type", "application / x-www-form-urlencoded");
 req.send ("id =" + encodeURIComponent (idTextField.value));

Saat mengirim nilai bentuk dari teknologi JavaScript, Anda harus mempertimbangkan nilai-nilai pengkodean lapangan. teknologi JavaScript mencakup encodeURIComponent() fungsi yang harus digunakan untuk memastikan bahwa konten lokal dikodekan dengan benar dan karakter khusus yang dikodekan dengan benar yang akan dilalui dalam permintaan HTTP.
4. Permintaan diproses oleh ValidateServlet .
servlet A dipetakan ke URI "memvalidasi" cek apakah ID user dalam database user.
servlet Sebuah proses sebuah XMLHttpRequest seperti itu akan ada permintaan HTTP lainnya. Contoh berikut ini menunjukkan sebuah server mengekstrak id parameter dari permintaan dan memvalidasi apakah parameter telah diambil.
 ValidateServlet public class extends HttpServlet {
    
     swasta ServletContext konteks;
     private HashMap pengguna = HashMap baru ();
 
     void init publik (ServletConfig config) throws ServletException {
         super.init (config);
         this.context = config.getServletContext ();
         users.put ("greg", "data akun");
         users.put ("duke", "data akun");
     }

     public void doGet (HttpServletRequest request, HttpServletResponse respon)
         throws IOException, ServletException {

         String targetId = request.getParameter ("id");

         if ((targetId = null)! & &! users.containsKey (targetId.trim ())) {
             response.setContentType ("text / xml");
             response.setHeader ("Cache-Control", "no-cache");
             response.getWriter () menulis ("<message> valid </ message>").; 
         } Else {
             response.setContentType ("text / xml");
             response.setHeader ("Cache-Control", "no-cache");
             response.getWriter () menulis ("<message> tidak valid </ message>").; 
         }
     }
 }

Dalam contoh ini, sederhana HashMap digunakan untuk menampung para pengguna. Dalam kasus contoh ini, mari kita asumsikan bahwa pengguna mengetik duke sebagai ID.
5. The ValidateServlet mengembalikan dokumen XML berisi hasil.
ID pengguna duke hadir dalam daftar ID pengguna dalam users HashMap . Para ValidateServlet akan menulis dokumen XML untuk respon berisi message elemen dengan nilai invalid . usecases Lebih kompleks mungkin memerlukan DOM, XSLT, atau API lainnya untuk menghasilkan respon.
 response.setContentType ("text / xml");
 response.setHeader ("Cache-Control", "no-cache");
 response.getWriter () menulis ("<message> tidak valid </ message>").; 

Pengembang harus menyadari dua hal. Pertama, Content-Type harus disetel ke text/xml . Kedua, Cache-Control harus diatur untuk no-cache . The XMLHttpRequest objek akan memproses permintaan hanya yang dari pada Content-Type hanya text/xml , dan pengaturan Cache-Control untuk no- cache akan menjaga browser dari lokal tanggapan caching untuk kasus-kasus di mana duplikat permintaan untuk URL yang sama (termasuk parameter URL ) dapat kembali respon yang berbeda.
6. The XMLHttpRequest objek menyebut callback() fungsi dan proses hasilnya.
The XMLHttpRequest objek ini dikonfigurasi untuk memanggil callback() berfungsi bila ada perubahan pada readyState dari XMLHttpRequest objek. Mari kita asumsikan panggilan kepada yang ValidateServlet dibuat dan readyState adalah 4 , menandakan XMLHttpRequest panggilan selesai. Status kode HTTP 200 menandakan interaksi HTTP sukses.
 fungsi callback () {
     if (req.readyState == 4) {
         if (req.status == 200) {
             / / Update DOM HTML berdasarkan pada apakah atau tidak berlaku pesan
         }
     }
 }

Browser mempertahankan sebuah representasi objek dari dokumen-dokumen yang ditampilkan (disebut sebagai Dokumen Object Model atau DOM). teknologi JavaScript di halaman HTML memiliki akses ke DOM, dan API tersedia yang memungkinkan teknologi JavaScript untuk memodifikasi DOM setelah halaman tersebut telah dimuat.
Setelah permintaan sukses, kode teknologi JavaScript dapat mengubah DOM dari halaman HTML. Representasi objek dokumen XML yang diambil dari ValidateServlet tersedia untuk kode teknologi JavaScript menggunakan req.responseXML , di mana req adalah XMLHttpRequest objek. API DOM menyediakan sarana untuk teknologi JavaScript untuk menavigasi isi dari dokumen itu dan menggunakannya untuk memodifikasi konten DOM dari halaman HTML. Representasi string dokumen XML yang dikembalikan dapat diakses dengan menelepon req.responseText . Sekarang mari kita lihat bagaimana menggunakan API DOM dalam teknologi JavaScript dengan melihat dokumen XML berikut kembali dari ValidateServlet .
 <message>
   berlaku
  </ Pesan>

Contoh ini merupakan sebuah fragmen XML sederhana yang berisi pengirim message unsur, yang hanya string valid atau invalid . Contoh lebih maju mungkin berisi lebih dari satu pesan dan nama yang valid yang dapat dipresentasikan kepada pengguna:
 fungsi parseMessage () {
  var pesan = req.responseXML.getElementsByTagName ("pesan") [0];
  setMessage (message.childNodes [0] nodeValue.);
 }

The parseMessages() Fungsi akan memproses dokumen XML diambil dari ValidateServlet . Fungsi ini akan memanggil setMessage() dengan nilai message elemen untuk memperbarui DOM HTML.
7. HTML DOM diperbarui.
teknologi JavaScript bisa mendapatkan referensi untuk setiap elemen dalam HTML DOM menggunakan sejumlah API. Cara yang disarankan untuk mendapatkan referensi ke elemen adalah untuk memanggil document.getElementById("userIdMessage") , dimana "userIdMessage" adalah atribut ID dari elemen yang muncul dalam dokumen HTML. Dengan mengacu pada elemen, JavaScript teknologi sekarang dapat digunakan untuk memodifikasi atribut elemen; memodifikasi properti gaya elemen, atau menambah, menghapus, atau memodifikasi elemen anak.
Salah satu cara umum untuk mengubah isi tubuh elemen adalah untuk mengatur innerHTML properti pada elemen seperti pada contoh berikut.
 <script type="text/javascript">

 ...

 fungsi setMessage (pesan) {
     var mdiv = document.getElementById ("userIdMessage");
     if (pesan == "tidak valid") {
        mdiv.innerHTML = "<div style=\"color:red\"> Id User tidak valid </ div>";
     } Else {
        mdiv.innerHTML = "<div style=\"color:green\"> Hari Id User </ div>";
     }
 }
 </ Script>
 <body>
 <div id="userIdMessage"> </ div>
 </ Body>

Bagian-bagian dari halaman HTML yang terkena dampak adalah re-diberikan segera setelah pengaturan dari innerHTML . Jika innerHTML properti mengandung unsur-unsur seperti <image> atau <iframe> , isi yang ditentukan oleh elemen-elemen diambil dan diberikan juga. Ajax aplikasi seperti Google Maps menggunakan teknik menambahkan elemen gambar dengan panggilan Ajax untuk secara dinamis membangun peta.
Kelemahan utama dengan pendekatan ini adalah bahwa elemen HTML hardcoded sebagai string di kode teknologi JavaScript. Hardcoding dalam kode HTML markup teknologi JavaScript bukan praktik yang baik karena membuat kode sulit untuk membaca, mempertahankan, dan memodifikasi. Pertimbangkan menggunakan teknologi JavaScript DOM API untuk membuat atau memodifikasi elemen HTML dalam kode teknologi JavaScript. Mencampurkan presentasi dengan kode teknologi JavaScript sebagai string akan membuat halaman sulit untuk membaca dan mengedit.
Cara lain untuk memodifikasi DOM HTML untuk secara dinamis menciptakan elemen baru dan menambahkan mereka sebagai anak-anak untuk elemen target seperti dalam contoh berikut.
 <script type="text/javascript">

 ...

 fungsi setMessage (pesan) {
      var userMessageElement = document.getElementById ("userIdMessage");
      var messageText;
      if (pesan == "tidak valid") {
          userMessageElement.style.color = "merah";
          messageText = "User Id tidak valid";
      } Else {
          userMessageElement.style.color = "hijau";
          messageText = "Hari Id User";
      }
      var messageBody = document.createTextNode (messageText);
      / / Jika elemen messageBody telah dibuat sederhana menggantinya dinyatakan
      / / Menambahkan unsur baru
      jika (userMessageElement.childNodes [0]) {
          userMessageElement.replaceChild (messageBody, userMessageElement.childNodes [0]);
      } Else {
          userMessageElement.appendChild (messageBody);
      }
 }
 </ Script>
 <body>
 <div id="userIdMessage"> </ div>
 </ Body>

Contoh kode menunjukkan bagaimana teknologi JavaScript DOM API dapat digunakan untuk membuat atau mengubah elemen elemen pemrograman. Dukungan untuk teknologi JavaScript DOM API dapat berbeda di berbagai browser, sehingga Anda harus berhati-hati saat mengembangkan aplikasi.

Final Thoughts
Meskipun banyak dari imbalan ini dicatat, pendekatan ini memiliki beberapa tantangan juga:
  • Kompleksitas: Server-side pengembang akan perlu memahami bahwa logika presentasi akan diperlukan dalam halaman HTML klien serta dalam logika sisi server untuk menghasilkan konten XML yang dibutuhkan oleh klien halaman HTML. halaman HTML pengembang perlu memiliki pemahaman dasar tentang teknologi JavaScript untuk membuat fungsionalitas baru Ajax. Pilihan lain seperti Proyek jMaki dan Proyek Dynamic Faces menyediakan cara bagi pengembang Java lebih baik menggunakan fungsionalitas Ajax tanpa memerlukan pengetahuan yang mendalam tentang teknologi JavaScript.
  • Standardisasi dari XMLHttpRequest objek: The XMLHttpRequest object adalah belum menjadi bagian dari spesifikasi teknologi JavaScript, yang berarti bahwa perilaku tersebut dapat bervariasi, tergantung pada klien. Itu terbaik untuk menggunakan perpustakaan seperti Dojo , yang menyediakan solusi fallback untuk membuat interaksi Ajax transparan bahkan pada browser lama yang tidak mendukung XMLHttpRequest Object:.
  • implementasi teknologi JavaScript: interaksi Ajax sangat tergantung pada teknologi JavaScript, yang memiliki perbedaan halus tergantung pada klien. Lihat QuirksMode.org untuk rincian lebih lanjut tentang perbedaan khusus browser. Pertimbangkan untuk menggunakan perpustakaan seperti Dojo , yang membahas banyak perbedaan.
  • Debug: Ajax aplikasi juga sulit untuk debug karena logika pengolahan tertanam baik di klien dan server. Browser pengaya seperti Mozilla Firebug telah muncul untuk membuat debuging lebih mudah. Kerangka kerja seperti Google Web Toolkit telah muncul untuk memungkinkan untuk klien dan server-perjalanan debugging bulat.
  • Mengamankan sumber daya dan melindungi data Anda: Anda dapat melihat sisi klien teknologi JavaScript hanya dengan memilih View Source dari Ajax-enabled halaman HTML. Sebuah aplikasi berbasis Ajax buruk dirancang bisa membuka diri untuk hacker atau plagiarisme. Saat memberikan layanan Ajax, Anda harus berhati-hati untuk memastikan bahwa layanan tersebut tersedia hanya untuk mereka yang dimaksudkan. Lihat Membatasi Akses ke Ajax Layanan Anda untuk informasi lebih lanjut mengenai perlindungan layanan Anda.
Kita telah melihat bahwa Ajax interaksi dapat memecahkan banyak masalah. teknologi Java menyediakan dasar yang baik untuk mengembangkan dan menyebarkan aplikasi berbasis Ajax dengan API untuk mengikat dalam pengolahan HTTP, database, layanan web, pengolahan XML, dan objek bisnis. Dengan pemahaman yang lebih baik dari model interaksi, aplikasi saat ini bisa menjadi lebih interaktif, memberikan pengguna akhir dengan pengalaman yang lebih baik.
Menggunakan Ajax mengharuskan Anda menggunakan browser versi terbaru yang mendukung XMLHttpRequest objek yang diperlukan untuk interaksi Ajax. Menggunakan Ajax juga membutuhkan banyak sisi klien teknologi JavaScript dan CSS. Sebagai arsitek aplikasi atau pengembang, Anda akan perlu mempertimbangkan kebutuhan memiliki aplikasi yang kaya terhadap mendukung browser, kompleksitas arsitektur, dan pelatihan pengembang. Sebagai model pemrograman Ajax berkembang, teknologi yang sudah ada dan kerangka kerja akan membuat transisi ini lebih mudah.
Apa yang jelas adalah bahwa aplikasi web menonjol adalah semakin menjadi lebih interaktif. Apakah Anda?
Untuk Informasi Lebih Lanjut
Tentang Penulis
Greg Murray adalah Sun Microsystems insinyur, arsitek Ajax dan memimpin spesifikasi servlet mantan dan mantan anggota tim cetak biru, di mana ia fokus di web tier dan internasionalisasi. Dia adalah salah satu penulis Merancang Aplikasi Enterprise Dengan Java 2 Platform, Enterprise Edition dan Perancangan Web Services Dengan Platform J2EE 1.4 (Addison-Wesley).

SHARE THIS POST   

  • Facebook
  • Twitter
  • Myspace
  • Google Buzz
  • Reddit
  • Stumnleupon
  • Delicious
  • Digg
  • Technorati
Author: Mohammad
Mohammad is the founder of STC Network which offers Web Services and Online Business Solutions to clients around the globe. Read More →

1 comment:

  1. JOs om,tapi belum saya baca pusing duluan,wkwkwkwk

    ReplyDelete