Saya menggunakan webapp di dua wadah yang berbeda (Tomcat dan Jetty), tetapi servlet default mereka untuk menyajikan konten statis memiliki cara berbeda dalam menangani struktur URL yang ingin saya gunakan ( detail ).
Karena itu saya ingin memasukkan servlet kecil di webapp untuk menyajikan konten statisnya sendiri (gambar, CSS, dll.). Servlet harus memiliki properti berikut:
- Tidak ada ketergantungan eksternal
- Sederhana dan andal
- Dukungan untuk
If-Modified-Since
tajuk (yaitugetLastModified
metode khusus ) - (Opsional) dukungan untuk penyandian gzip, etag, ...
Apakah servlet semacam itu tersedia di suatu tempat? Yang paling dekat yang bisa saya temukan adalah contoh 4-10 dari buku servlet.
Pembaruan: Struktur URL yang ingin saya gunakan - jika Anda bertanya-tanya - cukup:
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
Jadi semua permintaan harus diteruskan ke servlet utama, kecuali jika itu untuk static
path. Masalahnya adalah servlet default Tomcat tidak memperhitungkan ServletPath (sehingga mencari file statis di folder utama), sementara Jetty melakukannya (sehingga terlihat di static
folder).
sumber
Jawaban:
Saya datang dengan solusi yang sedikit berbeda. Agak hack-ish, tapi ini pemetaannya:
Ini pada dasarnya hanya memetakan semua file konten dengan ekstensi ke servlet default, dan yang lainnya ke "myAppServlet".
Ini bekerja di Jetty dan Tomcat.
sumber
*.sth
. Jika seseorang akan mendapatkan url,example.com/index.jsp?g=.sth
ia akan mendapatkan sumber file jsp. Atau saya salah? (Saya baru di Java EE) Saya biasanya menggunakan pola url/css/*
dan lainTidak perlu untuk implementasi kustom sepenuhnya dari servlet default dalam hal ini, Anda dapat menggunakan servlet sederhana ini untuk membungkus permintaan dengan implementasi kontainer:
sumber
Saya mendapatkan hasil yang baik dengan FileServlet , karena mendukung hampir semua HTTP (etags, chunking, dll.).
sumber
Template abstrak untuk servlet sumber daya statis
Sebagian didasarkan pada blog ini dari tahun 2007, inilah templat abstrak yang dimodernisasi dan dapat digunakan kembali untuk servlet yang menangani caching dengan benar
ETag
,,If-None-Match
danIf-Modified-Since
(tetapi tidak ada dukungan Gzip dan Range; hanya untuk membuatnya tetap sederhana; Gzip dapat dilakukan dengan filter atau melalui konfigurasi wadah).Gunakan bersama-sama dengan antarmuka di bawah ini yang mewakili sumber daya statis.
Yang Anda butuhkan hanyalah memperluas dari servlet abstrak yang diberikan dan mengimplementasikan
getStaticResource()
metode sesuai javadoc.Contoh nyata melayani dari sistem file:
Berikut ini adalah contoh nyata yang menyajikannya melalui URL seperti
/files/foo.ext
dari sistem file disk lokal:Contoh nyata melayani dari basis data:
Berikut ini adalah contoh nyata yang menyajikannya melalui URL seperti
/files/foo.ext
dari database melalui panggilan layanan EJB yang mengembalikan entitas Anda yang memilikibyte[] content
properti:sumber
files/%2e%2e/mysecretfile.txt
. Permintaan ini menghasilkanfiles/../mysecretfile.txt
. Saya mengujinya di Tomcat 7.0.55. Mereka menyebutnya pendakian direktori: owasp.org/index.php/Path_TraversalSaya akhirnya menggulung sendiri
StaticServlet
. Ini mendukungIf-Modified-Since
, encoding gzip dan seharusnya dapat melayani file statis dari file perang juga. Ini bukan kode yang sangat sulit, tetapi juga tidak sepenuhnya sepele.Kode tersedia: StaticServlet.java . Jangan ragu untuk berkomentar.
Pembaruan: Khurram bertanya tentang
ServletUtils
kelas yang dirujuk diStaticServlet
. Ini hanyalah sebuah kelas dengan metode tambahan yang saya gunakan untuk proyek saya. Satu-satunya metode yang Anda butuhkan adalahcoalesce
(yang identik dengan fungsi SQLCOALESCE
). Ini kodenya:sumber
Menilai dari contoh informasi di atas, saya pikir seluruh artikel ini didasarkan pada perilaku yang disadap di Tomcat 6.0.29 dan sebelumnya. Lihat https://issues.apache.org/bugzilla/show_bug.cgi?id=50026 . Tingkatkan ke Tomcat 6.0.30 dan perilaku di antara (Tomcat | Jetty) harus bergabung.
sumber
svn diff -c1056763 http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk/
. Akhirnya, setelah menandai WONTFIX ini +3 tahun yang lalu!coba ini
Sunting: Ini hanya valid untuk spesifikasi servlet 2.5 dan lebih tinggi.
sumber
Saya memiliki masalah yang sama dan saya menyelesaikannya dengan menggunakan kode 'default servlet' dari basis kode Tomcat.
https://github.com/apache/tomcat/blob/master/java/org/apache/catalina/servlets/DefaultServlet.java
The DefaultServlet adalah servlet yang melayani sumber daya statis (jpg, html, css, gif dll) di Tomcat.
Servlet ini sangat efisien dan memiliki beberapa properti yang Anda tetapkan di atas.
Saya pikir ini kode sumber, adalah cara yang baik untuk memulai dan menghapus fungsionalitas atau depedensi yang tidak Anda butuhkan.
sumber
org.apache.*
. Bagaimana Anda bisa menggunakannya dengan Jetty?Saya menemukan tutorial yang bagus di web tentang beberapa solusi. Ini sederhana dan efisien, saya menggunakannya di beberapa proyek dengan pendekatan gaya url REST:
http://www.kuligowski.pl/java/rest-style-urls-and-url-mapping-for-static-content-apache-tomcat,5
sumber
Saya melakukan ini dengan memperluas tomcat DefaultServlet ( src ) dan mengganti metode getRelativePath ().
... Dan inilah pemetaan servlet saya
sumber
Untuk melayani semua permintaan dari aplikasi Spring serta /favicon.ico dan file JSP dari / WEB-INF / jsp / * yang akan diminta oleh AbstrakUrlBasedView Spring Anda dapat memetakan ulang servlet jsp dan servlet default:
Kami tidak dapat mengandalkan pola-* .jsp url pada pemetaan standar untuk servlet jsp karena pola jalur '/ *' cocok sebelum pemetaan ekstensi dicentang. Memetakan servlet jsp ke folder yang lebih dalam berarti cocok terlebih dahulu. Pencocokan '/favicon.ico' persis terjadi sebelum pencocokan pola jalur. Pencocokan jalur yang lebih dalam akan berfungsi, atau pencocokan yang tepat, tetapi tidak ada pencocokan ekstensi yang dapat melewati pencocokan jalur '/ *'. Memetakan '/' ke servlet default tampaknya tidak berfungsi. Anda akan berpikir persis '/' akan mengalahkan pola path '/ *' pada springapp.
Solusi filter di atas tidak berfungsi untuk permintaan JSP diteruskan / disertakan dari aplikasi. Untuk membuatnya berfungsi, saya harus menerapkan filter ke springapp secara langsung, pada saat itu pencocokan pola-url tidak berguna karena semua permintaan yang masuk ke aplikasi juga masuk ke filternya. Jadi saya menambahkan pencocokan pola ke filter dan kemudian belajar tentang servlet 'jsp' dan melihat bahwa itu tidak menghapus awalan path seperti servlet default tidak. Itu memecahkan masalah saya, yang tidak persis sama tetapi cukup umum.
sumber
Diperiksa untuk Tomcat 8.x: sumber daya statis berfungsi OK jika root servlet memetakan ke "". Untuk servlet 3.x itu bisa dilakukan oleh
@WebServlet("")
sumber
Gunakan org.mortbay.jetty.handler.ContextHandler. Anda tidak memerlukan komponen tambahan seperti StaticServlet.
Di rumah dermaga,
konteks $ cd
$ cp javadoc.xml static.xml
$ vi static.xml
...
Tetapkan nilai contextPath dengan awalan URL Anda, dan tetapkan nilai resourceBase sebagai jalur file konten statis.
Ini berhasil untuk saya.
sumber
Lihat StaticFile di JSOS: http://www.servletsuite.com/servlets/staticfile.htm
sumber