Di Java Servlets, seseorang dapat mengakses badan respon melalui response.getOutputStream()
atau response.getWriter()
. Haruskah seseorang memanggil .close()
ini OutputStream
setelah itu ditulis?
Di satu sisi, ada nasihat Blochian untuk selalu menutup OutputStream
s. Di sisi lain, saya tidak berpikir bahwa dalam kasus ini ada sumber daya yang mendasarinya yang perlu ditutup. Buka / tutup soket dikelola di tingkat HTTP, untuk memungkinkan hal-hal seperti koneksi persisten dan semacamnya.
java
servlets
outputstream
Steven Huwig
sumber
sumber
close()
yang tidak melakukan apa-apa. Yang harus Anda lakukan adalah menutup setiap sumber daya yang dapat ditutup.Jawaban:
Biasanya Anda tidak harus menutup aliran. Kontainer servlet akan secara otomatis menutup aliran setelah servlet selesai dijalankan sebagai bagian dari siklus hidup permintaan servlet.
Misalnya, jika Anda menutup aliran, streaming tidak akan tersedia jika Anda menerapkan Filter .
Karena itu, jika Anda menutupnya, tidak ada hal buruk yang akan terjadi selama Anda tidak mencoba menggunakannya lagi.
EDIT: tautan filter lain
EDIT2: adrian.tarau benar bahwa jika Anda ingin mengubah respon setelah servlet melakukan tugasnya, Anda harus membuat pembungkus yang memperluas HttpServletResponseWrapper dan menyangga keluaran. Ini untuk menjaga output agar tidak langsung ke klien tetapi juga memungkinkan Anda untuk melindungi jika servlet menutup aliran, sesuai kutipan ini (penekanan saya):
Artikel
Seseorang dapat menyimpulkan dari artikel resmi Sun bahwa menutup
OutputStream
dari servlet adalah sesuatu yang biasa terjadi, tetapi tidak wajib.sumber
Aturan umumnya adalah ini: jika Anda membuka aliran, maka Anda harus menutupnya. Jika tidak, sebaiknya tidak. Pastikan kodenya simetris.
Dalam kasus
HttpServletResponse
, ini sedikit kurang jelas, karena tidak jelas apakah panggilangetOutputStream()
adalah operasi yang membuka aliran. Javadoc hanya mengatakan bahwa itu "Returns a ServletOutputStream
"; sama untukgetWriter()
. Apa pun itu, yang jelas adalah bahwaHttpServletResponse
"memiliki" aliran / penulis, dan itu (atau wadah) bertanggung jawab untuk menutupnya lagi.Jadi untuk menjawab pertanyaan Anda - tidak, Anda tidak boleh menutup aliran dalam kasus ini. Penampung harus melakukan itu, dan jika Anda masuk ke sana sebelum itu, Anda berisiko memasukkan bug halus dalam aplikasi Anda.
sumber
close()
ketika saya selesai dengan aliran, klien segera kembali dan sisa servlet terus mengeksekusi. Bukankah itu membuat jawaban menjadi lebih relatif? sebagai lawan dari ya atau tidak yang pastiJika ada kemungkinan filter dipanggil pada sumber daya yang 'disertakan', Anda sebaiknya tidak menutup aliran. Ini akan menyebabkan sumber daya yang disertakan gagal dengan pengecualian 'aliran ditutup'.
sumber
Anda harus menutup aliran, kodenya lebih bersih karena Anda memanggil getOutputStream () dan aliran tidak diteruskan kepada Anda sebagai parameter, ketika biasanya Anda hanya menggunakannya dan tidak berusaha menutupnya. API Servlet tidak menyatakan bahwa jika aliran keluaran dapat ditutup atau tidak boleh ditutup, dalam hal ini Anda dapat menutup aliran dengan aman, wadah apa pun di luar sana akan menangani penutupan aliran jika tidak ditutup oleh servlet.
Berikut adalah metode close () di Jetty, mereka menutup aliran jika tidak ditutup.
Juga sebagai pengembang Filter Anda tidak boleh menganggap bahwa OutputStream tidak ditutup, Anda harus selalu meneruskan OutputStream lain jika Anda ingin mengubah konten setelah servlet melakukan tugasnya.
EDIT: Saya selalu menutup streaming dan saya tidak punya masalah dengan Tomcat / Jetty. Saya tidak berpikir Anda harus memiliki masalah dengan wadah apa pun, lama atau baru.
sumber
Argumen lain yang menentang penutupan
OutputStream
. Lihat servlet ini. Ini membuat pengecualian. Pengecualian dipetakan di web.xml ke kesalahan JSP:File web.xml berisi:
Dan error.jsp:
Saat Anda memuat
/Erroneous
di browser, Anda melihat halaman kesalahan yang menampilkan "Kesalahan". Tetapi jika Anda menghapus komentarout.close()
baris di servlet di atas, menerapkan ulang aplikasi, dan memuat ulang/Erroneous
Anda tidak akan melihat apa-apa di browser. Saya tidak tahu apa yang sebenarnya terjadi, tapi saya rasa ituout.close()
mencegah penanganan kesalahan.Diuji dengan Tomcat 7.0.50, Java EE 6 menggunakan Netbeans 7.4.
sumber