1. Filter Servlet
1.1 Apa itu filter
Filter adalah program yang berjalan di server sebelum halaman Servlet atau JSP yang terkait dengannya. Filter dapat dilampirkan ke satu atau lebih halaman servlet atau JSP dan dapat memeriksa informasi permintaan yang memasukkan sumber daya ini. Setelah ini, filter dapat dipilih sebagai berikut:
① Panggil sumber daya secara teratur (mis., Hubungi servlets atau halaman JSP).
② Gunakan informasi permintaan yang dimodifikasi untuk menghubungi sumber daya.
③Valls sumber daya, tetapi ubah sebelum mengirim respons ke klien.
④Blokir panggilan sumber daya, dan sebaliknya pergi ke sumber daya lain, mengembalikan kode status tertentu atau menghasilkan output penggantian.
1.2 Prinsip Dasar Filter Servlet
Ketika servlet digunakan sebagai filter, ia dapat memproses permintaan pelanggan. Setelah pemrosesan selesai, itu akan diserahkan ke filter berikutnya untuk diproses, sehingga permintaan klien diproses satu per satu dalam rantai filter sampai permintaan dikirim ke target. Misalnya, situs web memiliki halaman web yang mengirimkan "informasi pendaftaran yang dimodifikasi". Setelah pengguna mengisi informasi yang dimodifikasi dan mengirimkannya, server perlu melakukan dua tugas saat diproses: Tentukan apakah sesi klien valid; dan secara seragam menyandikan data yang dikirimkan. Kedua tugas ini dapat diproses dalam rantai filter yang terdiri dari dua filter. Ketika proses filter berhasil, data yang dikirimkan dikirim ke target akhir; Jika proses filter tidak berhasil, tampilan akan didistribusikan ke halaman kesalahan yang ditentukan.
2. Langkah Pengembangan Filter Servlet
Langkah -langkah untuk mengembangkan filter servlet adalah sebagai berikut:
① Tulis kelas servlet yang mengimplementasikan antarmuka filter.
② Konfigurasikan filter di web.xml.
Mengembangkan filter membutuhkan penerapan antarmuka filter. Antarmuka filter mendefinisikan metode berikut:
① Destory () dipanggil oleh wadah web untuk menginisialisasi filter ini.
② init (filterconfig filterconfig) dipanggil oleh wadah web untuk menginisialisasi filter ini.
③ Dofilter (Permintaan ServletRequest, Respons ServletResponse, Rantai FilterChain) Kode pemrosesan penyaringan spesifik.
3. Contoh kerangka filter
SimpleFilter1.java
Paket com.zj.sample; impor java.io.ioException; impor javax.servlet.filter; impor javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet. kelas publik SimpleFilter1 mengimplementasikan filter {@suppresswarnings ("tidak digunakan") filterconfig filterconfig pribadi; public void init (filterconfig config) melempar servletException {this.filterconfig = config; } public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) {coba {system.out.println ("dalam simpleFilter1: memfilter permintaan ..."); rantai.dofilter (permintaan, respons); // Kirim pemrosesan ke sistem filter berikutnya. } catch (ioException IoE) {ioe.printstacktrace (); } catch (ServletException SE) {SE.PrintStackTrace (); }} public void hancur () {this.filterconfig = null; }}
SimpleFilter2.java
Paket com.zj.sample; impor java.io.ioException; impor javax.servlet.filter; impor javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet. kelas publik SimpleFilter2 mengimplementasikan filter {@suppresswarnings ("tidak digunakan") filterconfig filterconfig pribadi; public void init (filterconfig config) melempar servletException {this.filterconfig = config; } public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) {coba {system.out.println ("dalam simpleFilter2: memfilter permintaan ..."); rantai.dofilter (permintaan, respons); // Kirim pemrosesan ke sistem filter berikutnya.out.println ("dalam SimpleFilter2: memfilter respons ..."); } catch (ioException IoE) {ioe.printstacktrace (); } catch (ServletException SE) {SE.PrintStackTrace (); }} public void hancur () {this.filterconfig = null; }}
Web.xml
<filter> <filter-name>filter1</filter-name> <filter-class>com.zj.sample.SimpleFilter1</filter-class></filter><filter-mapping> <filter-name>filter1</filter-name> <url-pattern>/*</url-pattern>//Filter</filter-mapping> <filter> <filter-name>filter2</filter-name> <nilter-class> com.zj.sample.simpleFilter2 </tilter-class> </tilter> <nyfiletpapping> <nilter-name> filter2 </tilter-name> <rerl-pattern>/*</url-pattern> // filter untuk semua kunjungan </filter-Mapping>/*
Buka halaman apa pun di wadah web untuk mengeluarkan hasilnya: (Perhatikan permintaan/respons pesanan yang dijalankan oleh filter)
Dalam SimpleFilter1: Menyaring permintaan ... di dalam SimpleFilter2: Menyaring permintaan ... di dalam SimpleFilter2: Menyaring respons ... di dalam SimpleFilter1: Menyaring respons ...
4. Laporan Filter
Mari kita bereksperimen dengan filter sederhana yang mencetak pesan ke output standar dengan memanggil halaman Servlet atau JSP yang relevan. Untuk mengimplementasikan fungsi ini, perilaku penyaringan dilakukan dalam metode dofilter. Setiap kali halaman Servlet atau JSP yang terkait dengan filter ini dipanggil, metode Dofilter menghasilkan cetakan yang mencantumkan host yang diminta dan URL panggilan. Karena metode getRequesturl terletak di httpservletRequest alih -alih servletRequest, objek servletRequest dibangun sebagai tipe httpservletRequest. Mari kita ubah SimpleFilter1.java di Bab 3.
SimpleFilter1.java
Paket com.zj.sample; impor java.io.ioException; impor java.util.date; impor javax.servlet.filter; impor javax.servlet.filterchain; impor javax.servlet.filterconfig; impor javax.servlet.servletexception; impor; javax.servlet.servletresponse; import javax.servlet.http.httpservletrequest; kelas publik SimpleFilter1 mengimplementasikan filter {@suppresswarnings ("tidak digunakan") filterconfig filterconfig pribadi; public void init (filterconfig config) melempar servletException {this.filterconfig = config; } public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) {coba {system.out.println ("dalam simpleFilter1: memfilter permintaan ..."); HttpservletRequest req = (httpservletRequest) permintaan; System.out.println (req.getRemotehost () + "mencoba mengakses" + req.getRequesturl () + "on" + new date () + "."); rantai.dofilter (permintaan, respons); System.out.println ("Dalam SimpleFilter1: memfilter respons ..."); } catch (ioException IoE) {ioe.printstacktrace (); } catch (ServletException SE) {SE.PrintStackTrace (); }} public void hancur () {this.filterconfig = null; }}
Pengaturan Web.xml tetap tidak berubah, di bab 3 yang sama.
tes:
Masukkan [url] http: // localhost: 8080/test4jsp/login.jsp [/url]
hasil:
Within SimpleFilter1:Filtering the Request...0:0:0:0:0:0:0:0:0:0:0:0:0:0:1 tried to access [url]http://localhost:8080/Test4Jsp/login.jsp[/url] on Sun Mar 04 17:01:37 CST 2007.Within SimpleFilter2:Filtering the Request...Within SimpleFilter2:Filtering the Respons ... di dalam SimpleFilter1: memfilter respons ...
5. Filter di Access (Menggunakan Servlets Untuk Menginisialisasi Parameter dalam Filter)
Berikut ini adalah mengatur rentang waktu akses normal menggunakan init untuk merekam akses yang tidak dalam periode waktu ini. Mari kita ubah SimpleFilter2.java di Bab 3.
SimpleFilter2.java.
Paket com.zj.sample; import java.io.ioException; impor java.text.dateFormat; impor java.util.calendar; impor java.util.gregoriancalendar; impor javax.servlet.filter; impor javax.servlet.filterchain; impor javax.filter; javax.servlet.servletcontext; import javax.servlet.servletException; impor javax.servlet.servletrequest; import javax.servlet.servletResponse; kelas publik SimpleFilter2 mengimplementasikan filter {@suppresswarnings ("tidak digunakan") konfigurasi filterconfig pribadi; Konteks Private ServletContext; Private int StartTime, Endtime; formatter private formatter; public void init (filterconfig config) melempar servletException {this.config = config; Context = config.getSerVletContext (); formatter = dateFormat.getDateTimeInstance (DateFormat.Medium, DateFormat.Medium); Coba {startTime = integer.parseint (config.getInitparameter ("startTime")); // web.xml endtime = integer.parseint (config.getInitparameter ("endtime")); // web.xml} orfault (numberformsception nfe) {// malformed or pm. StartTime = 22; // 10:00 endtime = 6; // 6:00 AM}} public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) {coba {system.out.println ("dalam simpleFilter2: memfilter permintaan ..."); HttpservletRequest req = (httpservletRequest) permintaan; Kalender Gregoriancalendar = Gregoriancalendar baru (); int currentTime = calendar.get (calendar.hour_of_day); if (isunusualtime (currentTime, startTime, endtime)) {context.log ("peringatan:" + req.getRemotehost () + "diakses" + req.getRequesturl () + "di" + purnatter.format (calendar.gettime ())); // File log berada di bawah log <ATALINA_HOME> /LOGS.One per hari. } rantai.dofilter (permintaan, respons); System.out .println ("Di dalam SimpleFilter2: memfilter respons ..."); } catch (ioException IoE) {ioe.printstacktrace (); } catch (ServletException SE) {SE.PrintStackTrace (); }} public void destroy () {} // Apakah waktu saat ini antara awal dan akhir // waktu yang ditandai sebagai waktu akses yang tidak normal? Private boolean isunusualtime (int currentTime, int startTime, int endtime) {// Jika waktu mulai kurang dari waktu akhir (yaitu, // mereka dua kali pada hari yang sama), maka waktu saat ini dianggap tidak biasa jika itu // antara awal dan akhir zaman. if (startTime <endtime) {return ((currentTime> = startTime) && (currentTime <endtime)); } // Jika waktu mulai lebih besar dari atau sama dengan waktu // akhir (yaitu, waktu mulai satu hari dan // waktu akhir adalah pada hari berikutnya), maka waktu saat ini dianggap tidak biasa jika tidak ada antara // akhir waktu dan mulai waktu. else {return (! isunusualtime (currentTime, endtime, startTime)); }}}
Pengaturan Web.xml tetap tidak berubah.
Mengenai pemrosesan log Tomcat, berikut adalah pengantar lebih lanjut. config.getSerVletContext (). Log ("Log Message") akan menulis informasi log ke folder <GATALINA_HOME>/LOG. Nama file harus localhost_log.2007-03-04.txt (satu dihasilkan per hari demi hari, dan dapat dilihat pada hari berikutnya). Untuk mendapatkan file log seperti itu, Anda harus memiliki:
<Logger classname = "org.apache.catalina.logger.filelogger" prefix = "catalina_log." suffix = ". txt" timestamp = "true"/>
6. Filter situs dilarang
Jika Anda ingin mengganggu proses penyaringan berikutnya di tengah jalan ketika filter Anda mendeteksi pengecualian yang tidak normal, Anda dapat melakukan ini:
public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) melempar servletException, ioException {httpservletRequest req = (permintaan httpservletRequest); Respons httpservletResponse res = (httpservletResponse); if (isunusualcondition (req)) {res.sendredirect ("http://www.somesite.com"); } else {chain.dofilter (req, res); }} Contoh berikut adalah filter situs terlarang. Jika Anda tidak ingin beberapa situs mengakses situs web Anda, Anda dapat mendaftarkan situsnya dalam nilai param Web.xml, dan kemudian menerapkan prinsip di atas untuk melompat keluar dari penyaringan reguler dan memberikan halaman yang dilarang.
BannedAccessFilter.java
Paket com.zj.sample; impor java.io.ioException; impor java.io.printwriter; impor java.net.malformedurlexception; import java.net.url; impor java.util. javax.servlet.filterconfig; impor javax.servlet.servletException; impor javax.servlet.servletrequest; import javax.servlet.servletResponse; kelas publik BannedAccessFilter mengimplementasikan filter {private hashset <string> BannedSitetable; /*** Tolak akses jika permintaan berasal dari situs spanduk atau dirujuk di sini* oleh situs spanduk. */ public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) melempar servletException, ioException {System.out.println ("Di dalam BannedAccessFilter: memfilter permintaan ..."); HttpservletRequest req = (httpservletRequest) permintaan; String requestHost = req.getRemotehost (); String ReferringHost = getReferringHost (req.getheader ("referer")); String BannedSite = null; Boolean ISBANned = false; if (BoNDSItEtable.Contains (requesthost)) {BannedSite = requesthost; Terbukukan = Benar; } else if (BoNDSItEteTable.Contains (ReferringHost)) {BannedSite = ReferringHost; Terbukukan = Benar; } if (ISBANned) {showwarning (response, bannedsite); } else {chain.dofilter (permintaan, respons); } System.out.println ("Di dalam BannedAccessFilter: memfilter respons ..."); } /*** Buat tabel situs spanduk berdasarkan parameter inisialisasi.* Ingat bahwa versi 2.3 dari API Servlet mengamanatkan penggunaan platform* Java 2. Dengan demikian, aman untuk menggunakan hashset (yang menentukan* apakah ada kunci yang diberikan) daripada hashtable clumsier* (yang memiliki nilai untuk setiap kunci).*/ Public void init (filterconfig config) melempar servletException {BanneredSitetable = hashset baru <string> (); String BannedSites = config.getInitparameter ("BannedSites"); // Set Token Default: Ruang Putih. StringTokenizer Tok = New StringTokenizer (BannedSites); while (Tok.hasmoretokens ()) {String BannedSite = Tok.nextToken (); BANNEDSITETABLE.ADD (BERNONDSITE); System.out.println ("Dilarang" + BannedSite); }} public void dihancurkan () {} Private String getReferringHost (String RefererRingUrlString) {try {url ReferringUrl = URL baru (ReferRerRingUrlString); return (referringurl.gethost ()); } catch (Malformedurlexception mue) {// Malformed atau Null Return (null); }} // Respons penggantian yang dikembalikan ke pengguna // yang berasal dari atau dirujuk di sini oleh situs spanduk. Private Void ShowWarning (respons servletResponse, string dilarsit) melempar servletException, ioException {response.setContentType ("Text/html"); Printwriter out = response.getWriter (); String doctype = "<! Doctype html public/"-// w3c // dtd html 4.0 " +" transisi // en/">/n"; out.println (doctype + "<html>/n" + "<head> <title> akses dilarang </iteme> </ade head>/n" + "<body bgcolor =/" white/">/n" + "<h1> akses dilarang </h1>/n" + "maaf, akses dari atau via + bo -site +" tidak ada + "tidak ada +" tidak ada + " +" no "no" no "no." no "no" no "no" no. no. " "</body> </html>"); }}
Web.xml
<nilter> <filter-name> BannedAccessFilter </tilter-name> <nilter-class> com.zj.sample.boNDeCacSfilter </tiler-class> <Ilin-param> <param-name> BannedSite </param-name> <param-value> [url] www.competingsite.com [/url] [Param-Value> [url] www.comppetingsite.com [/url] [URMOM [url] www.moreservlets.com [/url] 127.0.0.1//we uji ini </param-value> </init-param> </tilter> <nilter-Mapping> <nilter-name> BannedAccessFilter </filter-name> <ruR-pattern>/</url-pola> </filter-potping>
tes:
[url] http: // localhost: 8080/test4jsp/[/url]
hasil:
7. Ganti filter
7.1 Ubah respons
Filter dapat memblokir akses ke sumber daya atau mencegahnya diaktifkan. Tetapi jika filter ingin mengubah respons yang dihasilkan oleh sumber daya. Apa yang harus dilakukan? Tampaknya tidak ada cara untuk mengakses respons yang dihasilkan oleh sumber daya. Parameter kedua dofilter (ServletResponse) menyediakan cara untuk mengirim output baru ke klien, tetapi tidak memberikan filter dengan cara untuk mengakses output halaman servlet atau JSP. Mengapa ini terjadi? Karena halaman Servlet atau JSP bahkan belum dieksekusi ketika metode dofilter dipanggil untuk pertama kalinya. Setelah metode dofilter dalam objek filterchain dipanggil, tampaknya sudah terlambat untuk memodifikasi respons, yaitu bahwa data telah dikirim ke klien.
Namun, ada cara, yaitu, memodifikasi objek respons dari metode dofilter yang diteruskan ke objek filterchain. Secara umum, bangun cache dari semua versi output yang dihasilkan oleh halaman servlet atau jsp. Servlet API Versi 2.3 menyediakan sumber daya yang berguna untuk ini, yaitu kelas HttpservletResponsewrapper. Penggunaan kelas ini mencakup lima langkah berikut:
1) Buat pembungkus respons. Perpanjang javax.servlet.http.httpservletResponsewrapper.
2) Berikan printwriter yang cache output. Kelebihan Metode GetWriter, kembalikan printwriter yang menyimpan semua yang dikirim ke sana, dan menyimpan hasilnya ke bidang yang dapat diakses nanti.
3) Lewati pembungkus ini ke Dofilter. Panggilan ini legal karena httpservletResponsewrapper mengimplementasikan httpservletResponse.
4) Ekstrak dan ubah output. Setelah memanggil metode dofilter dari filterChain, output dari sumber daya asli dapat diperoleh dengan menggunakan mekanisme yang disediakan pada langkah 2. Anda dapat memodifikasi atau menggantinya selama itu cocok untuk aplikasi Anda.
5) Kirim output yang dimodifikasi ke klien. Karena sumber daya asli tidak lagi mengirimkan output ke klien (output ini sudah disimpan dalam pembungkus respons Anda), output ini harus dikirim. Dengan cara ini, filter Anda perlu mendapatkan printwriter atau outputstream dari objek respons asli dan meneruskan output yang dimodifikasi ke dalam aliran.
7.2 Pembungkus respons yang dapat digunakan kembali
Contoh berikut memberikan pembungkus yang dapat digunakan di sebagian besar aplikasi di mana filter ingin memodifikasi output sumber daya. Kelas Chararraywrapper membebani metode GetWriter untuk mengembalikan printwriter yang mengumpulkan semuanya dalam array karakter besar. Pengembang dapat memperoleh hasil ini dengan menggunakan TocharArray (arang asli []) atau tostring (string yang berasal dari char []).
Chararraywrapper.java
Paket com.zj.sample; import java.io.chararraywriter; impor java.io.printwriter; import javax.servlet.http.httpservletresponse; import javax.servlet.http.httpservletresponse; /** * Pembungkus respons yang mengambil semua yang biasanya dikeluarkan klien * output dan menyimpannya dalam satu array karakter besar. */kelas publik chararraywrapper memperluas httpservletResponsewrapper {private chararraywriter charwriter; /*** Menginisialisasi pembungkus. * <p> * Pertama, konstruktor ini memanggil konstruktor induk. Panggilan itu *kejam sehingga respons disimpan dan dengan demikian setheader, *setstatus, addCookie, dan sebagainya bekerja secara normal. * <p> * Kedua, konstruktor ini menciptakan chararraywriter yang akan * digunakan untuk mengumpulkan respons. */ public chararraywrapper (respons httpservletResponse) {super (respons); charwriter = new chararraywriter (); } /*** Ketika servlets atau halaman JSP meminta penulis, jangan beri mereka* yang asli. Sebaliknya, beri mereka versi yang menulis ke* array karakter. * Filter perlu mengirim isi array ke klien* (mungkin setelah memodifikasinya). */ public printwriter getWriter () {return (printwriter baru (charwriter)); } /*** Dapatkan representasi string dari seluruh buffer. * <p> * Pastikan <b> bukan </b> untuk memanggil metode ini beberapa kali pada pembungkus * yang sama. API untuk Chararraywriter tidak menjamin bahwa itu * "mengingat" nilai sebelumnya, sehingga panggilan tersebut kemungkinan akan membuat * string baru setiap saat. */ public string toString () {return (charwriter.toString ()); } /** Dapatkan array karakter yang mendasarinya. */ public char [] tochararray () {return (charwriter.tochararray ()); }}
7.3 Ganti filter
Berikut ini adalah aplikasi umum dari ChararrayWrapper yang diberikan di bagian sebelumnya: Mengubah filter untuk string target multipel ke string pengganti.
7.3.1 Filter Penggantian Umum
ReplaceFilter.java memberikan filter yang membungkus respons dalam charaRaryWrapper, meneruskan pembungkus ke dalam metode dofilter dari objek filterchain, mengekstrak nilai tipe string yang memberikan output dari semua sumber daya, menggantikan semua kemunculan string target dengan string pengganti, dan mengirimkan hasil yang dimodifikasi ke klien.
Ada dua hal yang perlu diperhatikan tentang filter ini. Pertama, ini adalah kelas abstrak. Untuk menggunakannya, Anda harus membuat subclass yang menyediakan implementasi metode GetTargetString dan GetReplacementsTring. Contoh perawatan ini diberikan dalam ayat berikutnya. Kedua, ini menggunakan kelas utilitas yang lebih kecil (lihat filterutils.java) untuk penggantian string yang sebenarnya. Anda dapat menggunakan paket ekspresi reguler baru alih-alih menggunakan metode tingkat rendah dan membosankan di String dan StringTokenizer.
Replacefilter.java
Paket com.zj.sample; impor java.io.ioException; impor java.io.printwriter; impor javax.servlet.filter; impor javax.servlet.filterchain; impor javax.servlet.filterconfig; impor javax.servlet javax.servlet.servletresponse; import javax.servlet.http.httpservletResponse; /*** Filter yang menggantikan semua kemunculan string yang diberikan dengan penggantian*. * Ini adalah kelas abstrak: Anda <i> harus </i> mengesampingkan metode getTargetString* dan getReplacementstring dalam subkelas.* Metode pertama ini menentukan string dalam respons* yang harus diganti. Yang kedua dari spesifikasi ini string* yang harus menggantikan setiap kemunculan string target. */kelas abstrak publik Replacefilter mengimplementasikan filter {private filterconfig config; public void dofilter (permintaan servletRequest, respons servletResponse, rantai filterchain) melempar servletException, ioException {chararraywrapper responseewrapper = respons baru chararraywrapper ((httpservletResponse)); // Invoke Resource, mengumpulkan output dalam pembungkus. chain.dofilter (permintaan, responseWrapper); // Ubah seluruh output menjadi satu string besar. String responseString = responseWrapper.toString (); // Dalam output, ganti semua kemunculan string target dengan penggantian // string. responseString = filterutils.replace (responseString, getTargetString (), getReplacementString ()); // Perbarui header panjang konten. updateHeaders (respons, responseString); Printwriter out = response.getWriter (); out.write (responseString); } /*** Simpan objek filterconfig jika subkelas menginginkannya. */ public void init (filterconfig config) melempar servletException {this.config = config; } protected filterconfig getFilterConfig () {return (config); } public void destroy () {} /*** String yang perlu diganti.* Mengganti metode ini di subkelas Anda. */ string abstrak publik getTargetString (); /*** String yang menggantikan target. Menggantikan metode ini di * subclass Anda. */ string abstrak publik getReplacementstring (); /*** memperbarui header respons. Versi sederhana ini hanya mengatur* header panjang konten, dengan asumsi bahwa kami menggunakan set karakter* yang menggunakan 1 byte per karakter.* Untuk set karakter lainnya, mengesampingkan metode ini untuk menggunakan* logika yang berbeda atau untuk menyerah pada koneksi HTTP yang persisten.* Dalam kasus terakhir ini, mintalah metode ini mengatur header koneksi* ke "tutup". */ public void updateHeaders (respons servletResponse, string responseString) {response.setContentLength (responseString.length ()); }}
Filterutils.java
paket com.zj.sample; /*** Utilitas kecil untuk membantu pembungkus respons yang mengembalikan string. * /Filterutils kelas publik { /*** Ubah semua kemunculan orig dalam penganiayaan untuk diganti. */ Public Static String REPLACE (String Mainstring, String Orig, String Replacement) {String result = ""; int oldIndex = 0; INT INDEX = 0; int origlength = orig.length (); while ((index = Mainstring.IndexOf (orig, oldIndex))! = -1) {hasil = hasil + mainstring.substring (oldIndex, index) + penggantian; oldIndex = index + origlength; } hasil = hasil + penganiayaan.substring (oldIndex); pengembalian (hasil); }} 7.3.2 Menerapkan filter penggantian karakter. Asumsikan bahwa Baidu memperoleh Google (hanya hipotesis), semua teks dengan kata Google di semua halaman harus diganti oleh Baidu! REPLACESITENAMEFILTER.java mewarisi replacefilter.java di atas untuk mengimplementasikan fungsi ini. REPLACESITENAMEFILTER.JAVAPACKAGE COM.ZJ.SAMPLE; Public Class ReplacesEnamefilter memperluas Replacefilter {public String getTargeString () {return ("Google.com.cn"); } public String getReplacementString () {return ("baidu.com"); }}
Web.xml
<filter> <nilter-name> REPLACESITEnamEfilter </tiler-name> <nilter-class> com.zj.sample.replacesitenamefilter </filter-class> </filter> <filter-mapping> <nilter-name> </filter-name> <Siler-pattern> <nilter-name> </filter-name> <rilter-pattern>/login.jspstenamefilter </filter-name> <rilter-pattern> /login.jspstenamefilter </filter-name> <rilter-name> <rilter-pattern>/login.jsppatner> </filter-name> <rilter-pattern> /login.jspatch </filter--name> </filter-pattern>
Hasil tes:
Sebelum memfilter
Setelah penyaringan
8. Filter Kompresi
Ada beberapa browser terbaru yang dapat menangani konten terkompresi, secara otomatis membongkar file terkompresi dengan GZIP sebagai nilai header respons pengkodean konten, dan kemudian memproses hasilnya seperti dokumen asli. Mengirim konten terkompresi seperti itu dapat menghemat banyak waktu, karena waktu yang diperlukan untuk mengompres dokumen di server dan kemudian membatalkan dokumen pada klien adalah sepele dibandingkan dengan waktu yang diperlukan untuk mengunduh file. Program Longservlet.java memberikan servlet dengan output teks polos yang panjang dan duplikat, servlet dewasa untuk kompresi. Jika Anda menggunakan GZIP, itu dapat mengompres output ke 1/300!
Ketika browser mendukung kemampuan kompresi ini, filter kompresi dapat menggunakan chararraywrapper yang diperkenalkan pada Bab 7 untuk mengompres konten. Konten berikut diperlukan untuk menyelesaikan tugas ini:
1) Kelas yang mengimplementasikan antarmuka filter. Kelas ini bernama CompressionFilter. Metode init menyimpan objek filterconfig di bidang jika subkelas perlu mengakses lingkungan servlet atau nama filter. Metode Tubuh Destori Kosong.
2) Objek respons yang dibungkus. Metode dofilter membungkus objek servletResponse dalam chararraywrapper dan melewati pembungkus ini ke metode dofilter dari objek filterchain. Setelah panggilan ini selesai, semua filter lain dan sumber daya akhir telah dieksekusi dan outputnya ada di dalam pembungkus. Dengan cara ini, dofilter asli mengekstraksi serangkaian karakter yang mewakili output dari semua sumber daya. Jika klien menyatakan bahwa mereka mendukung kompresi (mis., Mengambil GZIP sebagai nilai untuk header penyandian penerimaan), filter menambahkan GzipoutputStream ke ByteArrayOutputStream, salin array karakter ke dalam aliran ini, dan setel header respons pengkodean konten ke GZIP. Jika klien tidak mendukung GZIP, salin array karakter yang tidak dimodifikasi ke ByteArrayOutputStream. Akhirnya, Dofilter mengirimkan hasilnya ke klien dengan menulis seluruh array karakter (mungkin dikompresi) ke dalam outputStream yang terkait dengan respons asli.
3) Daftarkan LongServlet.
Compressionfilter.java
Paket com.zj.sample; import java.io.bytearrayoutputStream; import java.io.ioException; import java.io.outputstream; java.io.outputStreamWriter; import java.util.zip.gzipoutputStream; impor javax.servlet.filter; javax.servlet.filterconfig; impor javax.servlet.servletException; impor javax.servlet.servletrequest; import javax.servlet.servletresponse; impor javax.servlet.http.httpservletequest; impor JAVAX.Servlet /** * Filter yang mengompres output dengan GZIP (dengan asumsi bahwa browser mendukung * GZIP). */kelas publik CompresFilter mengimplementasikan filter {private filterconfig config; /*** Jika browser tidak mendukung GZIP, panggil sumber daya secara normal. Jika browser * <i> memang </i> Mendukung GZIP, atur header respons pengodean konten dan * meminta sumber daya dengan respons yang dibungkus yang mengumpulkan semua output. * Ekstrak output dan tuliskan ke array byte gzip. Akhirnya, tulis * array itu ke aliran output klien. ? Respons httpservletResponse res = (httpservletResponse); if (! iSgzipsupported (req)) {// Invoke Resource secara normal. rantai.dofilter (req, res); } else {// Tell browser Kami mengirimkannya data gzip. res.setHeader ("encoding konten", "gzip"); // Invoke Resource, mengumpulkan output dalam pembungkus. ChararrayWrapper ResponseWrapper = Chararraywrapper baru (res); rantai.dofilter (req, responseWrapper); // Dapatkan array karakter yang mewakili output. char [] responseChars = responseWrapper.tochararray (); // Buat penulis yang mengompres data dan memasukkannya ke dalam array byte. BytearrayoutputStream bytestream = new bytearrayoutputStream (); GzipoutputStream zipout = GzipoutputStream baru (bytestream); OutputStreamWriter tempout = outputStreamWriter baru (zipout); // Kompres output asli dan masukkan ke dalam array byte. tempout.write (responseChars); // GZIP Streams harus ditutup secara eksplisit. tempout.close (); // Perbarui header panjang konten. res.setContentLength (bytestream.size ()); // Kirim hasil terkompresi ke klien. OutputStream realout = res.getOutputStream (); bytestream.writeto (realout); }} /*** Simpan objek filterconfig jika subkelas menginginkannya. */ public void init (filterconfig config) melempar servletException {this.config = config; } protected filterconfig getFilterConfig () {return (config); } public void destrash () {} private boolean isgzipsupported (httpservletRequest req) {string browserencodings = req.getheader ("accept-encoding"); return ((browserencodings! = null) && (browserencodings.indexof ("gzip")! = -1)); }} Longservlet.javapackage com.zj.sample; import java.io.ioException; impor java.io.printwriter; impor javax.servlet.servletException; import javax.servlet.http.htpservlet; impor javax.servlet.htp.htp.htpservlet; impor javax.servlet.htp.htp.htpservlet; impor javax.servlet.htp.htp.htpservlet; impor javax.servlet.htp.htpsve javax.servlet.http.httpservletResponse; /*** servlet dengan <b> output long </b>. Digunakan untuk menguji efek kompresi * filter Bab 9. */ Kelas Publik LongServlet memperluas httpservlet {public void doGet (httpservletRequest, respons httpservletResponse) melempar servletException, iOException {respons.setContentType ("teks/ html"); Printwriter out = response.getWriter (); String doctype = "<! Doctype html public/"-// w3c // dtd html 4.0 " +" transisi // en/">/n"; String title = "long page"; out.println (Doctype + "<Html>/n" + "<Head> <title>" + title + "</title> </ head>/n" + "<body bgcolor =/"#fdf5e6/">/n" + "<h1 align =/" center/"" + " +" </h1>/n "); String line = "bla, bla, bla, bla, bla." + "Yadda, yadda, yadda, yadda."; untuk (int i = 0; i <10000; i ++) {out.println (line); } out.println ("</body> </html>"); }}
Web.xml
<nilter> <nilter-name> compressionfilter </tiler-name> <nilter-class> com.zj.sample.compressionfilter </filter-class> </tiler> <nilter-Mapping> <nilter-name> compressionFilter </tiler-name> <servlet-name> LongServlet </servlet-name> </filter-name> <servlet> Longservlet </servlet-name> </filterpapppaping> <servlet> <servlet-class> com.zj.sample.longservlet </servlet-class> </servlet> <servlet-mapping> <servlet-name> LongServlet </servlet-name> <rats-pola>/longservlet </rerser-pola> </servlet-papping>