ServletContext
Ketika wadah servlet (seperti Apache Tomcat ) mulai, itu akan menyebarkan dan memuat semua aplikasi webnya. Ketika aplikasi web dimuat, wadah servlet membuat ServletContext
sekali dan menyimpannya di memori server. Aplikasi web web.xml
dan semua web-fragment.xml
file yang disertakan diuraikan, dan masing-masing <servlet>
, <filter>
dan <listener>
ditemukan (atau masing-masing kelas dijelaskan dengan @WebServlet
, @WebFilter
dan @WebListener
masing - masing) dipakai satu kali dan disimpan dalam memori server juga. Untuk setiap filter instantiated, init()
metodenya dipanggil dengan yang baru FilterConfig
.
Ketika Servlet
memiliki <servlet><load-on-startup>
atau @WebServlet(loadOnStartup)
nilai lebih besar dari 0
, maka init()
metode ini juga dipanggil saat startup dengan yang baru ServletConfig
. Servlet tersebut diinisialisasi dalam urutan yang sama yang ditentukan oleh nilai tersebut ( 1
adalah 1, 2
2, dll). Jika nilai yang sama ditetapkan untuk lebih dari satu servlet, maka masing-masing servlets dimuat dalam urutan yang sama seperti yang muncul dalam web.xml
, web-fragment.xml
atau @WebServlet
classloading. Jika nilai "load-on-startup" tidak ada, init()
metode akan dipanggil kapan saja permintaan HTTP mengenai servlet untuk pertama kalinya.
Ketika wadah servlet selesai dengan semua langkah inisialisasi yang dijelaskan di atas, maka ServletContextListener#contextInitialized()
akan dipanggil.
Ketika servlet kontainer menutup, itu membongkar semua aplikasi web, memanggil destroy()
metode semua servlets yang diinisialisasi dan filter, dan semua ServletContext
, Servlet
, Filter
dan Listener
contoh yang menghancurkan. Akhirnya ServletContextListener#contextDestroyed()
akan dipanggil.
HttpServletRequest dan HttpServletResponse
Wadah servlet dilampirkan ke server web yang mendengarkan permintaan HTTP pada nomor port tertentu (port 8080 biasanya digunakan selama pengembangan dan port 80 dalam produksi). Ketika klien (misalnya pengguna dengan browser web, atau menggunakan programURLConnection
) mengirim permintaan HTTP, wadah servlet membuat objek HttpServletRequest
dan baru HttpServletResponse
dan melewati mereka melalui apa pun yang ditentukan Filter
dalam rantai dan, akhirnya, Servlet
instance.
Dalam kasus filter , doFilter()
metode dipanggil. Ketika kode penampung servlet memanggil chain.doFilter(request, response)
, permintaan dan tanggapan berlanjut ke filter berikutnya, atau tekan servlet jika tidak ada filter yang tersisa.
Dalam kasus servlets , service()
metode dipanggil. Secara default, metode ini menentukan salah satu doXxx()
metode yang akan digunakan berdasarkan request.getMethod()
. Jika metode yang ditentukan tidak ada dari servlet, maka kesalahan HTTP 405 dikembalikan dalam respons.
Objek permintaan menyediakan akses ke semua informasi tentang permintaan HTTP, seperti URL, header, string kueri, dan badan. Objek respons memberikan kemampuan untuk mengontrol dan mengirim respons HTTP seperti yang Anda inginkan, misalnya, memungkinkan Anda untuk mengatur header dan isi (biasanya dengan konten HTML yang dihasilkan dari file JSP). Ketika respons HTTP dilakukan dan diselesaikan, objek permintaan dan respons didaur ulang dan tersedia untuk digunakan kembali.
HttpSession
Ketika klien mengunjungi webapp untuk pertama kalinya dan / atau HttpSession
diperoleh untuk pertama kalinya melalui request.getSession()
, wadah servlet membuat HttpSession
objek baru , menghasilkan ID panjang dan unik (yang bisa Anda dapatkan session.getId()
), dan menyimpannya di server. Penyimpanan. Wadah servlet juga menetapkan a Cookie
di Set-Cookie
header respons HTTP dengan JSESSIONID
sebagai namanya dan ID sesi unik sebagai nilainya.
Sesuai spesifikasi cookie HTTP (kontrak yang harus dipatuhi oleh setiap browser web dan server web yang layak), klien (browser web) diharuskan untuk mengirim cookie ini kembali dalam permintaan berikutnya di Cookie
header selama cookie tersebut valid (cookie tersebut valid) yaitu ID unik harus merujuk ke sesi yang tidak kedaluwarsa dan domain dan jalurnya benar). Menggunakan monitor lalu lintas HTTP bawaan browser Anda, Anda dapat memverifikasi bahwa cookie tersebut valid (tekan F12 di Chrome / Firefox 23+ / IE9 +, dan periksa tab Net / Network ). Wadah servlet akan memeriksa Cookie
tajuk setiap permintaan HTTP yang masuk untuk mengetahui keberadaan cookie dengan nama JSESSIONID
dan menggunakan nilainya (ID sesi) untuk mendapatkan yang terkait HttpSession
dari memori server.
The HttpSession
tetap hidup sampai telah diam (yaitu tidak digunakan dalam permintaan) untuk lebih dari nilai batas waktu yang ditentukan dalam <session-timeout>
, pengaturan di web.xml
. Nilai batas waktu default ke 30 menit. Jadi, ketika klien tidak mengunjungi aplikasi web lebih lama dari waktu yang ditentukan, wadah servlet merusak sesi. Setiap permintaan berikutnya, bahkan dengan cookie yang ditentukan, tidak akan memiliki akses ke sesi yang sama lagi; wadah servlet akan membuat sesi baru.
Di sisi klien, cookie sesi tetap hidup selama instance browser berjalan. Jadi, jika klien menutup instance browser (semua tab / windows), maka sesi tersebut dibuang ke sisi klien. Dalam instance browser baru, cookie yang terkait dengan sesi tidak akan ada, sehingga cookie tidak akan lagi dikirim. Hal ini menyebabkan pembuatan yang sama sekali baru HttpSession
, dengan cookie sesi yang sama sekali baru digunakan.
Pendeknya
- The
ServletContext
hidup selama kehidupan aplikasi web. Itu dibagikan di antara semua permintaan di semua sesi.
- The
HttpSession
hidup selama klien berinteraksi dengan aplikasi web dengan contoh browser yang sama, dan sesi belum habis waktunya di sisi server. Itu dibagikan di antara semua permintaan dalam sesi yang sama .
- Itu
HttpServletRequest
dan HttpServletResponse
hidup dari saat servlet menerima permintaan HTTP dari klien, sampai respons lengkap (halaman web) telah tiba. Itu tidak dibagikan di tempat lain.
- Semua
Servlet
, Filter
dan Listener
contoh hidup selama aplikasi web hidup. Mereka dibagikan di antara semua permintaan di semua sesi.
- Apa pun
attribute
yang didefinisikan ServletContext
, HttpServletRequest
dan HttpSession
akan hidup selama objek yang dipermasalahkan hidup. Objek itu sendiri mewakili "ruang lingkup" dalam kerangka kerja manajemen kacang seperti JSF, CDI, Spring, dll. Kerangka kerja tersebut menyimpan kacang scoping mereka sebagai attribute
lingkup pencocokan terdekat.
Keamanan Thread
Yang mengatakan, perhatian utama Anda mungkin keamanan benang . Anda sekarang harus tahu bahwa servlet dan filter dibagikan di antara semua permintaan. Itu hal yang menyenangkan tentang Java, itu multithreaded dan utas berbeda (baca: permintaan HTTP) dapat menggunakan contoh yang sama. Kalau tidak akan terlalu mahal untuk dibuat ulang, init()
dan destroy()
mereka untuk setiap permintaan tunggal.
Anda juga harus menyadari bahwa Anda tidak boleh menetapkan permintaan atau data cakupan sesi sebagai variabel instan dari servlet atau filter. Ini akan dibagikan di antara semua permintaan lain di sesi lain. Itu bukan thread-safe! Contoh di bawah menggambarkan ini:
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
Lihat juga:
PHPSESSID
cookie, ASP.NET denganASP.NET_SessionID
cookie, dan sebagainya. Itu juga alasan penulisan ulang URL;jsessionid=xxx
karena beberapa kerangka kerja JSP / Servlet MVC secara otomatis disukai. Pastikan ID sesi tidak pernah dibuka di URL atau dengan cara lain di laman web sehingga pengguna yang tidak sadar tidak akan diserang.Sesi
Singkatnya: server web mengeluarkan pengidentifikasi unik untuk setiap pengunjung pada kunjungan pertamanya . Pengunjung harus membawa kembali kartu identitas itu untuk dikenali di waktu berikutnya. Pengidentifikasi ini juga memungkinkan server untuk memisahkan dengan benar objek yang dimiliki oleh satu sesi terhadap sesi lainnya.
Instansiasi Servlet
Jika beban-on-startup adalah palsu :
Jika beban-on-startup adalah benar :
Setelah dia berada di mode layanan dan di alur, servlet yang sama akan bekerja pada permintaan dari semua klien lain.
Mengapa bukan ide yang baik untuk memiliki satu instance per klien? Pikirkan tentang ini: Apakah Anda akan mempekerjakan satu orang pizza untuk setiap pesanan yang datang? Lakukan itu dan Anda akan keluar dari bisnis dalam waktu singkat.
Muncul dengan risiko kecil. Ingat: pria lajang ini menyimpan semua informasi pesanan di sakunya: jadi jika Anda tidak berhati-hati tentang keamanan utas pada servlet , ia mungkin akhirnya memberikan pesanan yang salah kepada klien tertentu.
sumber
to many requests at this moment. try again later
Session in Java servlets sama dengan sesi dalam bahasa lain seperti PHP. Ini unik untuk pengguna. Server dapat melacaknya dengan cara yang berbeda seperti cookie, penulisan ulang url dll. Artikel Java doc ini menjelaskannya dalam konteks Java servlets dan menunjukkan bahwa bagaimana tepatnya sesi dikelola adalah detail implementasi yang diserahkan kepada perancang server. Spesifikasi hanya menetapkan bahwa itu harus dipertahankan sebagai unik bagi pengguna di beberapa koneksi ke server. Lihat artikel ini dari Oracle untuk informasi lebih lanjut tentang kedua pertanyaan Anda.
Sunting Ada tutorial yang sangat baik di sini tentang cara bekerja dengan sesi di dalam servlets. Dan di sini adalah bab dari Sun tentang Java Servlets, apa yang mereka dan bagaimana menggunakannya. Di antara dua artikel itu, Anda harus bisa menjawab semua pertanyaan Anda.
sumber
ServletContext
objek. Objek itu memiliki nol, satu, atau lebih objek sesi - kumpulan objek sesi. Setiap sesi diidentifikasi oleh semacam string pengidentifikasi, seperti yang terlihat dalam kartun pada jawaban lainnya. Pengidentifikasi itu dilacak pada klien dengan cookie atau penulisan ulang URL. Setiap objek sesi memiliki variabelnya sendiri.Ketika wadah servlet (seperti Apache Tomcat) dijalankan, ia akan membaca dari file web.xml (hanya satu per aplikasi) jika ada yang salah atau muncul kesalahan di konsol sisi wadah, jika tidak, ia akan menyebarkan dan memuat semua web aplikasi dengan menggunakan web.xml (dinamakan demikian sebagai deployment descriptor).
Selama fase instantiation servlet, instance servlet siap tetapi tidak dapat melayani permintaan klien karena hilang dengan dua bagian informasi:
1: informasi konteks
2: informasi konfigurasi awal
Mesin servlet membuat objek antarmuka servletConfig merangkum informasi yang hilang di atas ke dalamnya panggilan mesin servlet init () dari servlet dengan menyediakan referensi objek servletConfig sebagai argumen. Setelah init () benar-benar dieksekusi, servlet siap untuk melayani permintaan klien.
T) Dalam masa hidup servlet berapa kali instantiasi dan inisialisasi terjadi ??
A) hanya sekali (untuk setiap permintaan klien dibuat utas baru) hanya satu contoh servlet yang melayani sejumlah permintaan klien yaitu, setelah melayani satu server permintaan klien tidak mati. Ia menunggu permintaan klien lain yaitu batasan CGI (untuk setiap permintaan klien dibuat proses baru) diatasi dengan servlet (mesin servlet internal membuat utas).
Q) Bagaimana konsep sesi bekerja?
A) kapan saja getSession () dipanggil pada objek HttpServletRequest
Langkah 1 : objek permintaan dievaluasi untuk ID sesi masuk.
Langkah 2 : jika ID tidak tersedia, objek HttpSession baru dibuat dan sesi ID yang sesuai dihasilkan (yaitu dari HashTable) sesi ID disimpan ke objek respons httpservlet dan referensi objek HttpSession dikembalikan ke servlet (doGet / doPost) .
Langkah 3 : jika ID objek sesi baru yang tersedia tidak dibuat, sesi ID diambil dari pencarian objek permintaan yang dibuat dalam kumpulan sesi dengan menggunakan ID sesi sebagai kuncinya.
Setelah pencarian berhasil, ID sesi disimpan ke dalam HttpServletResponse dan referensi objek sesi yang ada dikembalikan ke doGet () atau doPost () dari UserDefineservlet.
catatan:
1) ketika kontrol keluar dari kode servlet ke klien jangan lupa bahwa objek sesi dipegang oleh wadah servlet yaitu, mesin servlet
2) multithreading diserahkan kepada pengembang servlet orang untuk mengimplementasikan mis., Menangani beberapa permintaan klien, tidak ada masalah dengan kode multithread
Formulir inshort:
Sebuah servlet dibuat ketika aplikasi dijalankan (ditempatkan pada wadah servlet) atau ketika diakses pertama kali (tergantung pada pengaturan load-on-startup) ketika servlet dipakai, metode init () dari servlet disebut kemudian servlet (satu-satunya instance) menangani semua permintaan (layanannya () metode dipanggil oleh banyak utas). Itu sebabnya tidak disarankan untuk melakukan sinkronisasi di dalamnya, dan Anda harus menghindari variabel instan dari servlet ketika aplikasi tidak digunakan (wadah servlet berhenti), metode destroy () dipanggil.
sumber
Sesi - apa yang dikatakan Chris Thompson.
Instantiasi - servlet di-instantiated ketika kontainer menerima permintaan pertama yang dipetakan ke servlet (kecuali servlet dikonfigurasikan untuk memuat saat startup dengan
<load-on-startup>
elemen di dalamnyaweb.xml
). Contoh yang sama digunakan untuk melayani permintaan berikutnya.sumber
Spesifikasi Servlet JSR-315 dengan jelas mendefinisikan perilaku wadah web dalam metode layanan (dan doGet, doPost, doPut dll.) (2.3.3.1 Masalah Multithreading, Halaman 9):
sumber
Seperti yang jelas dari penjelasan di atas, dengan menerapkan SingleThreadModel , servlet dapat dijamin keamanannya oleh wadah servlet. Implementasi kontainer dapat dilakukan dengan 2 cara:
1) Serialisasi permintaan (antrian) ke satu contoh - ini mirip dengan servlet TIDAK menerapkan SingleThreadModel TETAPI menyinkronkan metode layanan / doXXX; ATAU
2) Membuat kumpulan instance - yang merupakan pilihan yang lebih baik dan trade-off antara upaya boot-up / inisialisasi / waktu servlet sebagai terhadap parameter pembatasan (waktu memori / CPU) dari lingkungan hosting servlet.
sumber
Tidak. Servlets tidak aman untuk Thread
Ini memungkinkan Anda mengakses lebih dari satu utas sekaligus
jika Anda ingin menjadikannya Servlet sebagai Thread aman., Anda dapat melakukannya
Implement SingleThreadInterface(i)
yang merupakan Antarmuka kosong tidak adametode
atau kita bisa mencari metode sinkronisasi
kita dapat membuat seluruh metode layanan disinkronkan dengan menggunakan disinkronkan
kata kunci di depan metode
Contoh::
atau kita dapat menempatkan blok kode di blok Disinkronkan
Contoh::
Saya merasa bahwa blok Sinkronisasi lebih baik daripada membuat seluruh metode
Disinkronkan
sumber