Struktur Struts2
1. Mengapa menggunakan kerangka kerja?
(1) Kerangka kerja secara otomatis menyelesaikan banyak tugas sepele
Untuk Struts2, ini membantu kami dengan mudah menyelesaikan konversi tipe data, verifikasi data, internasionalisasi, dll.
Tugas umum dalam pengembangan web. Ada juga mode templat yang banyak digunakan di musim semi, yang semuanya membuat proses pengembangan kami lebih otomatis dan cerdas. Menggunakan kerangka kerja adalah untuk menghindari menciptakan kembali roda dan menyalin ulang kode templat ini.
Kerangka kerja memungkinkan kita untuk lebih fokus pada masalah tingkat yang lebih tinggi daripada pada alur kerja umum dan tugas-tugas dasar.
(2) Menggunakan kerangka kerja berarti dengan anggun mewarisi arsitektur di balik kerangka kerja
Arsitektur di balik kerangka ini biasanya mendefinisikan serangkaian alur kerja. Yang perlu kita lakukan adalah melampirkan kode aplikasi spesifik untuk proses ini, sehingga kita dapat menikmati berbagai manfaat yang dibawa oleh kerangka kerja. Kadang -kadang kita juga dapat menolak aturan arsitektur kerangka kerja, tetapi kerangka kerja biasanya memberikan arsitekturnya dengan cara yang sulit ditolak. Sangat sederhana sehingga Anda dapat mewarisi arsitektur yang sangat baik dengan anggun dan gratis, jadi mengapa tidak melakukannya?
(3) Lebih mudah menemukan orang yang terlatih menggunakan kerangka kerja
Saya hampir tidak pernah menggunakan kerangka kerja apa pun di seluruh proyek perusahaan saya sebelumnya, dan mencari layanan layanan (mirip dengan JNDI)
Untuk mencatat pencetakan (mirip dengan log4j), dan kemudian ke kumpulan koneksi database (mirip dengan DBCP), semuanya diimplementasikan oleh personel internal sendiri. Pertama, itu karena proyek ini relatif lama, dan mungkin tidak ada kerangka kerja open source untuk digunakan pada waktu itu. Kedua, itu karena strategi konservatif perusahaan, dan khawatir bahwa menggunakan kerangka kerja open source yang tidak stabil dapat membawa risiko pada proyek. Ini mungkin benar di lingkungan pada waktu itu, dan manajemen senior perusahaan secara alami akan mempertimbangkan seluruh proyek dari perspektif yang lebih besar.
Namun, ketika proyek secara bertahap menjadi lebih besar dan ada lebih banyak kerangka kerja open source yang lebih baik di dunia, jika beberapa kerangka kerja open source matang tidak dapat direfaktor dalam waktu dan diperkenalkan, hasil akhirnya mungkin bahwa pengembang yang baru direkrut harus mempelajari sistem yang kompleks ini dari awal (semua sistem internal, dan tidak ada bantuan di internet), dan berhati -hatilah dari berbagai magang di internal (semua kerangka internal, dan tidak ada bantuan di internet), dan berhati -hatilah dari berbagai magang di internal (semua kerangka internal.
Biaya benar -benar terlalu tinggi.
(4) Kerangka kerja internal tidak dapat mengimbangi pengembangan industri
Bug dalam kerangka internal yang disebutkan sebelumnya. Untuk kerangka kerja open source, mungkin ada tim pendiri kerangka kerja, sejumlah besar penggemar open source,
Komunitas open source untuk mendukungnya. Kekuatan orang tidak terbatas, dan kecepatan perbaikan bug dapat dibayangkan. Ini dari open source baru -baru ini
Proses perbaikan bug dari teman teks dapat dilihat. Banyak bug yang telah ditangguhkan sejak lama telah dengan cepat diselesaikan oleh penggemar setelah mereka adalah open source, tetapi bagaimana dengan kerangka internal? Setelah orang -orang yang mengembangkannya meninggalkan perusahaan, tidak ada yang akan membaca kode sumbernya tanpa bug besar. Kesenjangannya jelas!
(5) Tentu saja, menggunakan kerangka kerja bukanlah keuntungan besar.
Seperti yang disebutkan sebelumnya, menggunakan kerangka kerja yang belum matang berisiko, dan lebih baik menjadi konservatif untuk proyek yang tidak begitu radikal.
(Kecuali ini adalah sekelompok fanatik teknologi yang bebas dan tidak terkendali yang dapat memutuskan kerangka kerja apa yang akan digunakan atas kebijaksanaan mereka sendiri, itu benar -benar berkah)
Sama seperti Sequioa, layanan ketersediaan tinggi Java ha yang saya gunakan sebelumnya, kerangka kerja ini tidak lagi didukung oleh perusahaan pengembangan, dan risikonya bahkan lebih besar.
Selain itu, saat menggunakan beberapa kerangka kerja yang tidak umum, Anda juga harus memperhatikan protokol lisensi kode sumber kerangka kerja, dan tidak merujuknya sesuka hati dalam proyek.
Ubah kode sumber kerangka kerja untuk menghindari perselisihan hukum yang tidak perlu.
2. Arsitektur di belakang struts2
Karena kami telah menganalisis begitu banyak manfaat dari kerangka kerja sebelumnya, kami secara alami akan mulai belajar menggunakan Struts2. Tetapi menggunakan struts2
Jenis arsitektur elegan apa yang akan diwariskannya? Faktanya, dari tingkat abstraksi yang lebih tinggi, masih merupakan model MVC yang kita kenal.
Menurut contoh HelloWorld sebelumnya, Controller C (FilterDispatcher) adalah apa yang kami nyatakan di Web.xml
Kelas Inti Struts2. Dan Model M adalah kelas aksi NewsAction kami. Dan View V secara alami adalah News.jsp. Konsep model tampaknya agak kabur. Apa itu model? Faktanya, konsep ini yang terdengar sangat kata benda berisi data bisnis yang secara statis ditransmisikan dari front-end web dan implementasi logika bisnis.
Beberapa orang mungkin mengatakan bahwa arsitektur ini bukan hal baru, ada banyak kerangka kerja MVC, apa perbedaan antara ini dan kerangka kerja lainnya? Mari kita bedah struts2 pada tingkat abstraksi yang lebih rendah dan lihat apa yang membuatnya unik.
Sekilas, terlihat sangat rumit. Jika kita hanya melihatnya dari perspektif pengguna, kita hanya perlu menerapkan bagian kuning selama pengembangan, yaitu, kita
Struts.xml, NewsAction dan news.jsp dalam instance HelloWorld. Hanya ini yang harus kita lakukan, seperti yang disebutkan sebelumnya, kita hanya perlu melakukan hal -hal yang sangat kecil dan kita menjadi bagian dari arsitektur yang sangat baik ini.
Sekarang lihat bagian lain. FilterDispatcher adalah filter servlet yang kami konfigurasi di web.xml, yang merupakan struts2
Semua aplikasi web Struts2 harus dikonfigurasi dengan cara ini. Selanjutnya, bagian biru dan hijau adalah inti dari Struts2. Dapat dikatakan bahwa kelas -kelas ini dirancang dengan cermat oleh pengembang Struts2.
(1) Klien mengirimkan permintaan, dan wadah J2EE mem -parsing paket HTTP dan merangkumnya menjadi httpservletRequest.
(2) FilterDispatcher mencegat permintaan ini dan mencari ActionMapper berdasarkan jalur permintaan untuk menentukan tindakan mana yang akan dihubungi.
(3) Menurut hasil pengembalian ActionMapper, FilterDispatcher mempercayakan ActionProxy untuk menemukan tindakan ini di struts.xml.
(4) ActionProxy menciptakan ActionInvocation dan memulai panggilan rekursif ke Interceptor dan Action.
(5) Setiap pencegat menyelesaikan tugasnya sendiri
(6) Panggilan untuk bertindak yang sebenarnya mengembalikan jalur hasil
(7) Objek hasil akan menghasilkan data pengembalian ke aliran
(8) Kembalikan httpservletResponse ke wadah J2EE, dan wadah mengirimkan paket http ke klien.
Ini adalah proses eksekusi Struts2. Objek inti adalah ActionInvocation dan Interceptor, serta ActionContext yang belum diperkenalkan.
ActionInvocation adalah penjadwalan total dari seluruh proses, yang sangat mirip dengan objek doa di Spring AOP. Banyak interseptor dibangun menjadi struts2. Yang paling penting adalah menyimpan parameter permintaan dan meneruskan data latar depan ke variabel anggota tindakan.
ActionContext adalah objek konteks global yang menyimpan data ini, dan yang paling penting adalah nilai yang digunakan untuk menyimpan instance tindakan.
Yang disebut global berarti bahwa ActionContext dapat diakses dalam aksi dan hasil, tetapi sebenarnya tipe threadlocal. Setiap utas permintaan akan memiliki contoh tindakan dan ActionContext.
Dapat dikatakan bahwa belajar struts2 terutama tentang belajar:
(1) Biarkan pencegat dan tindakan bekerja sama untuk menyelesaikan tugas.
(2) Simpan data latar depan ke dalam tindakan.
(3) Hasil mendapatkan data pengembalian dari tindakan melalui ValueStack.
3. Perbedaan antara Struts2 dan Struts1
Dari proses eksekusi di atas, kita sudah bisa melihat perbedaan besar antara Struts1 dan 2.
(1) Kemana perginya ActionForm? Apakah tindakan masih merupakan tindakan yang sama?
Yang paling jelas adalah bahwa kita tidak dapat melihat objek ActionForm di seluruh proses, dan meskipun tindakannya masih disebut nama ini, tampaknya itu sama sekali berbeda dari tindakan di Struts1.
Pertama -tama, ActionForm ditinggalkan, dan data yang dikirim dari meja depan dapat disimpan ke pojo mana pun. Hari Simpan dalam ActionForm terlebih dahulu dan kemudian menyalin ke objek DTO sudah berakhir. Kedua, pojo ini sebenarnya adalah variabel anggota dalam objek tindakan. Ini ada di struts1
Tidak mungkin untuk berbagi instance tindakan untuk semua permintaan dalam kasus ini. Sekarang Struts2 akan membuat instance tindakan untuk setiap permintaan, jadi ini berhasil. Ketiga, meskipun ini layak, tampaknya tindakan itu, sebagai model M dalam MVC, menyimpan data dan berisi logika bisnis. Apakah ini desain yang buruk? Sebenarnya, jika Anda memikirkannya dengan cermat, desain ini sangat nyaman, kami telah memperoleh data.
Anda dapat secara langsung mengoperasikan lapisan layanan. Tindakan tampaknya memiliki terlalu banyak tanggung jawab, tetapi tidak banyak.
(2) Bagaimana servlet front-end menjadi filter?
Kita tahu bahwa Struts1 dan Spring MVC keduanya digunakan sebagai pintu masuk melalui servlet front-end. Mengapa Struts2 menggunakan filter servlet?
Karena Struts2 didasarkan pada inti webwork, itu sama sekali berbeda dari Struts1. Webwork dapat dikatakan mengurangi aplikasi dan J2EE
Kopling API, seperti Mengubah ActionServlet ke filter Servlet, dan akses langsung ke httpservletRequest/respons.
Misalnya, POJO apa pun dapat berfungsi sebagai ActionForm, kelas apa pun dapat digunakan sebagai tindakan tanpa mengimplementasikan antarmuka tindakan, dll.
Oleh karena itu, Struts2 juga mewarisi desain non-invasif yang sangat baik ini.
Ini agak mirip dengan ide -ide desain Spring. Misalnya, antarmuka peralatan itu tidak perlu diimplementasikan sama sekali, untuk meminimalkan kopling antara kode aplikasi dan kerangka kerja. Invasivitas memang merupakan faktor penting untuk dipertimbangkan ketika merancang kerangka kerja.
(3) Ognl antara filter, aksi, dan hasil
Gambar berikut dapat dengan jelas menunjukkan bagaimana OGNL diintegrasikan ke dalam kerangka struts2.
Sangat nyaman untuk mengakses data yang beraksi menggunakan tag Struts2 di input inputForm.html dan kembali ke halaman resultPage.jsp
Ognl membuat akses ke sifat -sifat tindakan yang disimpan di ValueStack sama nyamannya dengan mengakses properti ValueStack sendiri.
Penggunaan OGNL yang luas adalah fitur utama dari Struts2. Termasuk nilai latar belakang yang lewat ke tindakan, hasil mengambil nilai dari tindakan, dll., Akan menggunakan OGNL dalam jumlah besar. Namun, refleksi banyak digunakan di OGNL. Saya pikir ini adalah salah satu alasan mengapa Struts2 tidak sebagus Struts1. Bagaimanapun, dibutuhkan harga tertentu untuk mendapatkan arsitektur yang fleksibel dan berpasangan rendah.
(4) Kekuatan Interceptor tidak terkalahkan
Fitur kuat lainnya di Struts2 adalah Interceptor Interceptor. Struts2 telah membangun sejumlah besar pencegat, yang memungkinkan sejumlah besar kode untuk digunakan kembali, mengotomatiskan apa yang sebelumnya kita sebut tugas sepele, sehingga memungkinkan Struts2 untuk mencapai tingkat pemisahan perhatian yang tinggi. Ini benar -benar model untuk penerapan ide -ide AOP dalam kerangka kerja!
Struts2 tiga metode transfer data
Struts2 menyediakan tiga cara untuk menyimpan parameter dalam permintaan HTTP: Atribut Javabean, objek Javabean, dan objek ModelDriven. Mari kita lihat tiga metode transfer data ini melalui contoh login yang paling umum. Kode halaman sangat sederhana. Formulir pengiriman berisi nama pengguna dan kata sandi. Anda bisa mendapatkan dua parameter ini dalam tindakan untuk memverifikasi apakah pengguna masuk dengan sukses.
1. Properti JavaBean
< %@ page contentType = "text/html; charset = utf-8" %> <html> <head> </head> <hody> <h1> halaman login </h1> <bentuk acti </div> <div> <label for = "password"> Kata sandi: </label> <input id = "password" name = "password" type = "password"/> </div> <ver> <label untuk = "RememberMe"> <input id = "RememberMe" name = "RememberMe" type = "CheckBox"/Remember Me </label> </nameMe = "RememberMe" type "/centang" </body> </html>
paket com.cdai.web.ssh.action; impor com.cda.web.ssh.request.loginRequest; impor com.cda.web.ssh.service.userservice; impor com.opensymphony.xwork2.action; impor com.opensymphony.xwork2.modeldriven; Loginaksi kelas publik mengimplementasikan tindakan {private string username; kata sandi string pribadi; UserServer UserService Private; @Override Public String execute () {System.out.println ("Login Action -" + Request); Sukses kembali; } public String getUserName () {request return; } public void setusername (string username) {this.username = username; } public String getPassWord () {return revand; } public void setPassword (kata sandi string) {this.password = kata sandi; }}Metode ini relatif sederhana, secara langsung menyimpan parameter dalam formulir ke properti dalam tindakan. Saat memverifikasi, tindakan mungkin juga perlu merangkum nama pengguna dan kata sandi ke dalam DTO untuk meneruskannya ke lapisan layanan untuk verifikasi. Jadi mengapa tidak melangkah lebih jauh dan menyimpan nama pengguna dan kata sandi langsung ke DTO.
2. Objek Javabean
< %@ page contentType = "Text/html; charset = utf-8" %> <html> <head> </head> <hody> <h1> Halaman login </h1> <bentuk action = "/cdai/login" Method = "POST"> <Div> <label untuk = "nama pengguna"> Nama: </label> <input = "" nameern "name." </div> <div> <label for = "password"> Kata sandi: </label> <input id = "password" name = "request.password" type = "password"/> </div> <Div> <label untuk = "RememberMe"> <Input ID = "RememberMe" Name = "RememberMe" Type = "Checkbox"/Remember <put/Label> </input "name =" centang "type =" centang "//label </input> </input =" input = "centang" centang " </form> </body> </html>
paket com.cdai.web.ssh.action; impor com.cda.web.ssh.request.loginRequest; impor com.cda.web.ssh.service.userservice; impor com.opensymphony.xwork2.action; impor com.opensymphony.xwork2.modeldriven; Loginaksi kelas publik mengimplementasikan tindakan {permintaan private LoginRequest; UserServer UserService Private; @Override Public String execute () {System.out.println ("Login Action -" + Request); Sukses kembali; } public LoginRequest getRequest () {request return; } public void setRequest (permintaan loginRequest) {this.Request = request; }} Ini memudahkan untuk menghubungi lapisan layanan secara langsung. Tetapi ada kerugian kecil yang ini memperdalam kedalaman nama parameter halaman, hanya menambahkan permintaan ke nama parameter
Awalan (nama atribut dalam tindakan) memungkinkan Struts2 untuk menyimpan parameter dengan benar dalam formulir ke objek permintaan melalui OGNL.
3. Objek ModelDriven
< %@ page contentType = "text/html; charset = utf-8" %> <html> <head> </head> <hody> <h1> halaman login </h1> <bentuk acti </div> <div> <label for = "password"> Kata sandi: </label> <input id = "password" name = "password" type = "password"/> </div> <ver> <label untuk = "RememberMe"> <input id = "RememberMe" name = "RememberMe" type = "CheckBox"/Remember Me </label> </nameMe = "RememberMe" type "/centang" </body> </html>
paket com.cdai.web.ssh.action; impor com.cda.web.ssh.request.loginRequest; impor com.cda.web.ssh.service.userservice; impor com.opensymphony.xwork2.action; impor com.opensymphony.xwork2.modeldriven; Loginaksi kelas publik mengimplementasikan tindakan, ModelDriven <LoginRequest> {Private LoginRequest Request = new LoginRequest (); UserServer UserService Private; @Override Public String execute () {System.out.println ("Login Action -" + Request); Sukses kembali; } @Override Public LoginRequest getModel () {request return; }} Dengan cara ini, satu lagi antarmuka yang dimodelkan diperlukan, dan objek yang disediakan oleh ModelDriven disimpan ke ValueStack, sehingga halaman latar depan dapat dilewati secara langsung
Nama atribut nama pengguna dan kata sandi menentukan nama parameter formulir.
Manakah dari tiga metode yang tidak boleh digeneralisasi? Itu tergantung pada kebutuhan spesifik proyek dan kemudian putuskan sendiri!