Bisakah saya mengecualikan beberapa url beton dari <url-pattern> di dalam <filter-mapping>?
127
Saya ingin beberapa filter beton diterapkan untuk semua url kecuali untuk satu beton (yaitu untuk /*kecuali untuk /specialpath).
Apakah ada kemungkinan untuk melakukan itu?
Kode sampel:
<filter><filter-name>SomeFilter</filter-name><filter-class>org.somproject.AFilter</filter-class></filter><filter-mapping><filter-name>SomeFilter</filter-name><url-pattern>/*</url-pattern><!-- the question is: how to modify this line? --><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping>
API Servlet standar tidak mendukung fasilitas ini. Anda mungkin ingin menggunakan filter penulisan ulang URL untuk ini seperti yang Tuckey's (yang mirip dengan HTTPD Apache mod_rewrite), atau menambahkan tanda centang pada doFilter()metode mendengarkan Filter pada /*.
String path =((HttpServletRequest) request).getRequestURI();if(path.startsWith("/specialpath/")){
chain.doFilter(request, response);// Just continue chain.}else{// Do your business stuff here for all paths other than /specialpath.}
Anda dapat, jika perlu, menentukan path-to-be-diabaikan sebagai init-paramfilter sehingga Anda bisa mengendalikannya di bagian web.xmlmanapun. Anda bisa mendapatkannya di filter sebagai berikut:
Jika filter merupakan bagian dari API pihak ke-3 dan karenanya Anda tidak dapat memodifikasinya, maka petakan pada yang lebih spesifik url-pattern, mis. /otherfilterpath/*Dan buat filter baru /*yang meneruskan jalur yang cocok dengan filter pihak ke-3.
Untuk menghindari filter ini akan memanggil dirinya sendiri dalam loop tak terbatas, Anda perlu membiarkannya hanya mendengarkan (mengirim) REQUESTdan filter pihak ke-3 FORWARDsaja.
Masalah saya adalah bahwa filter itu bukan milik saya, itu dari pustaka komponen.
Roman
4
Ypu harus mengambil filter pustaka compnent dan memperluasnya untuk menambahkan kode yang ingin Anda gunakan untuk melakukan pengecualian.
gbtimmon
@ BalusC Jika "/ specialpath" hanya melayani sumber daya statis seperti js, css dll, apakah chain.doFilter () membuat respons lebih lambat? Apakah ada metode untuk menyajikan sumber daya secara langsung tanpa merantai filter?
BenhurCD
@BenhurCD: Saya benar-benar tidak tahu bagaimana Anda bisa sampai pada masalah kinerja ini.
BalusC
13
Saya menggunakan pendekatan yang dijelaskan oleh Eric Daugherty : Saya membuat servlet khusus yang selalu menjawab dengan kode 403 dan meletakkan pemetaannya sebelum yang umum.
Pendekatan ini berfungsi saat Anda ingin mencegah filter tertentu dan semua yang berikut. Ini harus bekerja dengan baik jika Anda mis. ingin menyajikan beberapa konten sebagai sumber daya statis dalam wadah servlet Anda alih-alih membiarkan logika aplikasi Anda (melalui filter seperti GuiceFilter):
Petakan folder dengan file sumber daya statis Anda ke servlet default. Buat filter servlet dan letakkan di depan GuiceFilter di web.xml Anda. Di filter yang Anda buat, Anda dapat memisahkan antara meneruskan beberapa permintaan ke GuiceFilter dan lainnya langsung ke operator. Contoh berikut ...
Saya mencoba menggunakan solusi Anda, tetapi untuk file yang saya terapkan filter dan memutus rantai, saya mendapatkan kesalahan followin; Pengecualian tanpa tertangkap dilemparkan oleh filter Static Resource Filter: java.io.FileNotFoundException. Ada yang tahu kenapa?
shamaleyte
Dalam pengaturan multi-konteks, penggunaan .getRequestURI()akan rusak (menyebabkan 404 kemungkinan besar) karena .getRequestDispatcherdiselesaikan relatif terhadap jalur konteks . Jika jalur konteks Anda adalah /a, maka dalam contoh Anda permintaan URI akan /a/static, dan menggunakan getRequestDispatcher("/a/static")akan menyebabkannya untuk menyelesaikannya /a/a/static. Perbaiki: gunakan .getServletPath()sebagai ganti .getRequestURI(). Saya akan mengirimkan hasil edit untuk memperbaikinya, tetapi hanya ingin memberikan komentar FYI
Reid
3
Saya tidak berpikir Anda bisa, satu-satunya alternatif konfigurasi lain adalah untuk menghitung jalan yang ingin Anda filter, jadi alih-alih /*Anda bisa menambahkan beberapa untuk /this/*dan /that/*lain - lain, tetapi itu tidak akan mengarah ke solusi yang cukup ketika Anda memiliki banyak dari jalur tersebut.
Apa yang dapat Anda lakukan adalah menambahkan parameter ke filter yang memberikan ekspresi (seperti ekspresi reguler) yang digunakan untuk melewati fungsionalitas filter untuk jalur yang cocok. Wadah servlet masih akan memanggil filter Anda untuk url itu, tetapi Anda akan memiliki kontrol yang lebih baik atas konfigurasi.
Edit
Sekarang setelah Anda menyebutkan bahwa Anda tidak memiliki kendali atas filter, apa yang dapat Anda lakukan adalah mewarisi dari supermetode pemanggilan filter dalam metodenya kecuali ketika jalur url yang ingin Anda lewati ada dan ikuti rantai filter seperti @BalusC yang diusulkan, atau buat filter yang instantiate filter Anda dan delegasi dalam keadaan yang sama. Dalam kedua kasus, parameter filter akan mencakup parameter ekspresi yang Anda tambahkan dan orang-orang dari filter yang Anda warisi atau didelegasikan ke.
Keuntungan membangun filter pendelegasian (pembungkus) adalah Anda dapat menambahkan kelas filter dari filter terbungkus sebagai parameter dan menggunakannya kembali dalam situasi lain seperti ini.
Jika karena alasan apa pun Anda tidak dapat mengubah pemetaan filter asli ("/ *" dalam kasus saya) dan Anda mengirim ke filter pihak ketiga yang tidak dapat diubah, Anda dapat menemukan hal-hal berikut yang bermanfaat:
Mencegah jalan yang harus dilewati
Lewati dan jalankan cincin terakhir rantai filter (servlet itu sendiri)
Melompati dilakukan melalui refleksi, memeriksa contoh wadah dalam mode debug
Saya menggunakan pendekatan yang dijelaskan oleh Eric Daugherty : Saya membuat servlet khusus yang selalu menjawab dengan kode 403 dan meletakkan pemetaannya sebelum yang umum.
Memetakan fragmen:
Dan kelas servlet:
sumber
Pendekatan ini berfungsi saat Anda ingin mencegah filter tertentu dan semua yang berikut. Ini harus bekerja dengan baik jika Anda mis. ingin menyajikan beberapa konten sebagai sumber daya statis dalam wadah servlet Anda alih-alih membiarkan logika aplikasi Anda (melalui filter seperti GuiceFilter):
Petakan folder dengan file sumber daya statis Anda ke servlet default. Buat filter servlet dan letakkan di depan GuiceFilter di web.xml Anda. Di filter yang Anda buat, Anda dapat memisahkan antara meneruskan beberapa permintaan ke GuiceFilter dan lainnya langsung ke operator. Contoh berikut ...
web.xml
StaticResourceFilter.class
Sayangnya, jika Anda hanya ingin melewatkan satu langkah dalam rantai filter sambil mempertahankan langkah-langkah berikut, ini tidak akan berhasil.
sumber
.getRequestURI()
akan rusak (menyebabkan 404 kemungkinan besar) karena.getRequestDispatcher
diselesaikan relatif terhadap jalur konteks . Jika jalur konteks Anda adalah/a
, maka dalam contoh Anda permintaan URI akan/a/static
, dan menggunakangetRequestDispatcher("/a/static")
akan menyebabkannya untuk menyelesaikannya/a/a/static
. Perbaiki: gunakan.getServletPath()
sebagai ganti.getRequestURI()
. Saya akan mengirimkan hasil edit untuk memperbaikinya, tetapi hanya ingin memberikan komentar FYISaya tidak berpikir Anda bisa, satu-satunya alternatif konfigurasi lain adalah untuk menghitung jalan yang ingin Anda filter, jadi alih-alih
/*
Anda bisa menambahkan beberapa untuk/this/*
dan/that/*
lain - lain, tetapi itu tidak akan mengarah ke solusi yang cukup ketika Anda memiliki banyak dari jalur tersebut.Apa yang dapat Anda lakukan adalah menambahkan parameter ke filter yang memberikan ekspresi (seperti ekspresi reguler) yang digunakan untuk melewati fungsionalitas filter untuk jalur yang cocok. Wadah servlet masih akan memanggil filter Anda untuk url itu, tetapi Anda akan memiliki kontrol yang lebih baik atas konfigurasi.
Edit
Sekarang setelah Anda menyebutkan bahwa Anda tidak memiliki kendali atas filter, apa yang dapat Anda lakukan adalah mewarisi dari
super
metode pemanggilan filter dalam metodenya kecuali ketika jalur url yang ingin Anda lewati ada dan ikuti rantai filter seperti @BalusC yang diusulkan, atau buat filter yang instantiate filter Anda dan delegasi dalam keadaan yang sama. Dalam kedua kasus, parameter filter akan mencakup parameter ekspresi yang Anda tambahkan dan orang-orang dari filter yang Anda warisi atau didelegasikan ke.Keuntungan membangun filter pendelegasian (pembungkus) adalah Anda dapat menambahkan kelas filter dari filter terbungkus sebagai parameter dan menggunakannya kembali dalam situasi lain seperti ini.
sumber
Saya juga harus memfilter berdasarkan pola URL (/ {servicename} / api / stats /) dalam kode java.
Tetapi anehnya, servlet itu tidak mendukung pola url selain (/ *), Ini seharusnya menjadi kasus yang sangat umum untuk API servlet!
sumber
Saya telah menemukan masalah yang sama, tetapi saya menemukan server lain di bawah ini.
web.xml
filter.java
dengan cara ini Anda tidak perlu melecehkan kelas Filter beton.
sumber
Jika karena alasan apa pun Anda tidak dapat mengubah pemetaan filter asli ("/ *" dalam kasus saya) dan Anda mengirim ke filter pihak ketiga yang tidak dapat diubah, Anda dapat menemukan hal-hal berikut yang bermanfaat:
Karya-karya berikut di Weblogic 12.1.3:
sumber