Pertanyaan Bagaimana cara kerja servlet? Instansiasi, sesi, berbagi variabel dan multithreading


Misalkan, saya memiliki webserver yang menyimpan banyak servlets. Untuk informasi yang lewat di antara servlet-servlet tersebut, saya mengatur sesi dan variabel instan.

Sekarang, jika 2 atau lebih pengguna mengirim permintaan ke server ini lalu apa yang terjadi pada variabel sesi? Apakah mereka semua umum untuk semua pengguna atau mereka akan berbeda untuk setiap pengguna. Jika mereka berbeda, lalu bagaimana server dapat membedakan antara pengguna yang berbeda?

Satu lagi pertanyaan serupa, jika ada n pengguna mengakses servlet tertentu, maka servlet ini hanya dipakai pertama kalinya ketika pengguna pertama mengaksesnya atau apakah ia mendapatkan instantiated untuk semua pengguna secara terpisah? Dengan kata lain, apa yang terjadi pada variabel instan?


989
2018-06-24 00:16


asal


Jawaban:


ServletContext

Ketika wadah servlet (seperti Apache Tomcat) dijalankan, ia akan menyebarkan dan memuat semua aplikasi webnya. Ketika aplikasi web dimuat, wadah servlet menciptakan ServletContext sekali dan menyimpannya di memori server. Aplikasi web web.xml file diuraikan, dan masing-masing <servlet>, <filter> dan <listener> ditemukan (atau masing-masing kelas dianotasikan dengan @WebServlet, @WebFilter dan @WebListener masing-masing) dipakai sekali dan disimpan dalam memori server juga. Untuk setiap filter yang dipakai, itu init() metode dipanggil dengan yang baru FilterConfig.

Ketika kontainer servlet mati, ia membongkar semua aplikasi web, memanggil destroy() metode dari semua servlet dan filter yang diinisialisasi, dan semuanya ServletContext, Servlet, Filter dan Listener instance dibuang ke sampah.

Ketika sebuah Servlet mempunyai sebuah <servlet><load-on-startup> atau @WebServlet(loadOnStartup) nilai lebih besar dari 0, itu init() metode ini juga dipanggil saat startup dengan yang baru ServletConfig. Servlet tersebut diinisialisasi dengan urutan yang sama yang ditentukan oleh nilai tersebut (1 -> 1, 2 -> 2, dll). Jika nilai yang sama ditentukan untuk lebih dari satu servlet, maka masing-masing servlet tersebut dimuat dalam urutan yang muncul di web.xml, atau @WebServlet classloading. Jika nilai "load-on-startup" tidak ada, maka init() metode akan dipanggil setiap kali permintaan HTTP menyentuh servlet itu untuk pertama kalinya.

HttpServletRequest dan HttpServletResponse

Wadah servlet melekat pada server web yang mendengarkan permintaan HTTP pada nomor port tertentu (port 8080 biasanya digunakan selama pengembangan dan port 80 dalam produksi). Ketika seorang klien (pengguna dengan browser web) mengirim permintaan HTTP, wadah servlet menciptakan yang baru HttpServletRequest dan HttpServletResponse objek dan melewati mereka melalui didefinisikan Filter rantai dan, akhirnya, Servlet contoh.

Dalam kasus filter, yang doFilter() metode dipanggil. Ketika kode panggilannya chain.doFilter(request, response), permintaan dan tanggapan diteruskan ke filter berikutnya, atau tekan servlet jika tidak ada filter yang tersisa.

Dalam kasus servlet, yang service() metode dipanggil. Secara default, metode ini menentukan yang mana dari doXxx() metode untuk memohon berdasarkan dari 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 header dan body-nya. Objek respons menyediakan 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 selesai, baik objek permintaan dan respons didaur ulang dan dibuat untuk digunakan kembali.

HttpSession

Ketika klien mengunjungi webapp untuk pertama kalinya dan / atau HttpSession diperoleh untuk pertama kalinya melalui request.getSession(), wadah servlet menciptakan yang baru HttpSession objek, menghasilkan ID panjang dan unik (yang bisa Anda dapatkan session.getId()), dan menyimpannya di memori server. Wadah servlet juga menetapkan Cookie dalam Set-Cookie tajuk respons HTTP dengan JSESSIONID sebagai namanya dan ID sesi unik sebagai nilainya.

Sesuai dengan Spesifikasi cookie HTTP (kontrak yang layak untuk web browser dan server web harus mematuhi), klien (browser web) diperlukan untuk mengirim cookie ini kembali dalam permintaan berikutnya di Cookie tajuk selama cookie valid (mis. ID unik harus merujuk ke sesi yang belum kedaluwarsa dan domain dan lintasan sudah 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 Net / Network tab). Wadah servlet akan memeriksa Cookie tajuk setiap permintaan HTTP yang masuk untuk kehadiran cookie dengan nama tersebut JSESSIONID dan gunakan nilainya (ID sesi) untuk mendapatkan yang terkait HttpSession dari memori server.

Itu HttpSession tetap hidup sampai belum digunakan selama lebih dari nilai timeout yang ditentukan <session-timeout>, pengaturan di web.xml. Nilai waktu tunggu default menjadi 30 menit. Jadi, ketika klien tidak mengunjungi aplikasi web lebih lama dari waktu yang ditentukan, kontainer servlet merusak sesi. Setiap permintaan berikutnya, bahkan dengan cookie yang ditentukan, tidak akan memiliki akses ke sesi yang sama lagi; kontainer 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 contoh browser baru, cookie yang dikaitkan dengan sesi tidak akan ada, sehingga tidak lagi dikirim. Ini menyebabkan hal yang sama sekali baru HTTPSession yang akan dibuat, dengan cookie sesi yang benar-benar baru mulai digunakan.

Pendeknya

  • Itu ServletContext hidup selama aplikasi web hidup. Itu dibagi di antara semua permintaan dalam semua sesi.
  • Itu HttpSession hidup selama klien berinteraksi dengan aplikasi web dengan contoh browser yang sama, dan sesi belum habis waktu di sisi server. Itu dibagi di antara semua permintaan di sama sidang.
  • Itu HttpServletRequest dan HttpServletResponse hidup dari waktu servlet menerima permintaan HTTP dari klien, sampai respon lengkap (halaman web) telah tiba. ini tidak dibagikan di tempat lain.
  • Semua Servlet, Filter dan Listener contoh hidup selama aplikasi web hidup. Mereka dibagi di antara semua permintaan dalam semua sesi.
  • Apa saja attribute yang didefinisikan dalam ServletContext, HttpServletRequest dan HttpSession akan hidup selama objek yang dipertanyakan hidup. Objek itu sendiri mewakili "ruang lingkup" dalam kerangka manajemen kacang seperti JSF, CDI, Spring, dll. Kerangka kerja itu menyimpan biji-biji mereka yang dilingkari sebagai attribute dari lingkup pencocokan terdekatnya.

Keamanan Benang

Yang mengatakan, perhatian utama Anda mungkin keamanan benang. Anda sekarang harus tahu bahwa servlet dan filter dibagikan di antara semua permintaan. Itu hal yang bagus dari Java, itu thread multithreaded dan berbeda (baca: permintaan HTTP) dapat menggunakan instance yang sama. Jika tidak akan terlalu mahal untuk dibuat ulang, init() dan destroy() mereka untuk setiap permintaan tunggal.

Anda juga harus menyadari bahwa Anda seharusnya tak pernah menetapkan setiap permintaan atau sesi scoped data sebagai contoh variabel servlet atau filter. Ini akan dibagikan di antara semua permintaan lainnya di sesi lain. Itu tidak aman dari benang! Contoh di bawah ini 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:


1623
2018-06-24 02:41



Sesi

enter image description here enter image description here

Singkatnya: server web mengeluarkan pengidentifikasi unik setiap pengunjung pada dirinya pertama mengunjungi. Pengunjung harus membawa kembali ID itu agar dia dikenali di lain waktu. Pengidentifikasi ini juga memungkinkan server untuk memisahkan objek yang dimiliki oleh satu sesi dengan yang lain.

Instansiasi Servlet

Jika load-on-startup aku s Salah:

enter image description here enter image description here

Jika load-on-startup aku s benar:

enter image description here enter image description here

Begitu dia berada di mode layanan dan di alur, itu sama servlet akan mengerjakan permintaan dari semua klien lain.

enter image description here

Mengapa tidak ada ide bagus untuk memiliki satu contoh 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.

Itu datang dengan risiko kecil sekalipun. Ingat: pria lajang ini menyimpan semua informasi pesanan di sakunya: jadi jika Anda tidak berhati-hati keamanan benang di servlet, ia mungkin akhirnya memberikan perintah yang salah kepada klien tertentu.


394
2017-07-06 16:38



Sesi di servlets Java sama dengan sesi dalam bahasa lain seperti PHP. Ini unik untuk pengguna. Server dapat melacaknya dengan cara yang berbeda seperti cookie, url penulisan ulang, dll. Ini Dokumen Java Artikel menjelaskannya dalam konteks Java servlets dan menunjukkan bahwa persis bagaimana sesi dipertahankan adalah detail implementasi yang diserahkan kepada para perancang server. Spesifikasi hanya menetapkan bahwa itu harus dipertahankan sebagai unik untuk pengguna di beberapa koneksi ke server. Periksa artikel ini dari Oracle untuk informasi lebih lanjut tentang kedua pertanyaan Anda.

Edit Ada tutorial yang bagus sini tentang cara bekerja dengan sesi di dalam servlet. Dan sini adalah bab dari Sun tentang Java Servlets, apa itu dan bagaimana cara menggunakannya. Di antara kedua artikel itu, Anda harus bisa menjawab semua pertanyaan Anda.


40
2018-06-24 00:20



Ketika servletcontainer (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 kontainer, selain itu akan menyebarkan dan memuat semua aplikasi web dengan menggunakan web .xml (dinamakan demikian sebagai deskriptor penyebaran).

Selama fase instantiasi servlet, servletInstance sudah siap tetapi tidak dapat melayani permintaan klien karena hilang dengan dua bagian informasi:
1: informasi konteks
2: informasi konfigurasi awal

Mesin Servlet menciptakan objek antarmuka servletConfig yang merangkum informasi yang hilang di atas ke dalamnya mesin servlet memanggil init () dari servlet dengan memberikan referensi objek servletConfig sebagai argumen. Setelah init () adalah servlet yang selesai dijalankan siap untuk server permintaan klien.

T) Dalam waktu hidup servlet berapa kali instantiasi dan initalialization terjadi ??

A) hanya sekali (untuk setiap permintaan klien, utas baru dibuat) hanya satu contoh servlet melayani sejumlah permintaan klien yaitu, setelah melayani satu klien server permintaan tidak mati. Ini menunggu permintaan klien lain yaitu apa CGI (untuk setiap permintaan klien proses baru dibuat) keterbatasan diatasi dengan servlet (mesin servlet internal menciptakan untaian).

T) Bagaimana konsep sesi bekerja?

A) setiap kali getSession () dipanggil pada objek HttpServletRequest

Langkah 1: objek permintaan dievalauasi untuk ID sesi yang masuk.

Langkah 2: jika ID tidak avaiable objek HttpSession baru dibuat dan ID sesi yang terkait dihasilkan (yaitu HashTable) ID sesi disimpan ke objek respon httpservlet dan referensi objek HttpSession dikembalikan ke servlet (doGet / doPost).

Langkah 3: jika ID avaiable merek objek sesi baru tidak dibuat ID sesi diambil dari permintaan objek pencarian dibuat dalam koleksi sesi dengan menggunakan ID sesi sebagai kunci.

Setelah pencarian berhasil ID sesi disimpan ke HttpServletResponse dan referensi objek sesi yang ada dikembalikan ke doGet () atau doPost () dari UserDefineservlet.

catatan:

1) ketika kontrol berpindah dari kode servlet ke klien jangan lupa bahwa objek sesi sedang ditahan oleh servletcontainer yaitu, servletengine

2) multithreading diserahkan kepada servlet devlopers orang untuk diimplementasikan yaitu., Menangani beberapa permintaan client tidak ada yang mengganggu tentang kode multithread

Bentuk inshort:

Sebuah servlet dibuat ketika aplikasi dijalankan (itu digunakan pada kontainer servlet) atau ketika pertama kali diakses (tergantung pada pengaturan load-on-startup) ketika servlet diinstansiasi, metode init () dari servlet dipanggil lalu servlet (satu-satunya contoh) menangani semua permintaan (metode servisnya () dipanggil dengan beberapa utas). Itulah mengapa tidak disarankan untuk memiliki sinkronisasi di dalamnya, dan Anda harus menghindari variabel instan dari servlet saat aplikasi tidak digunakan (kontainer servlet berhenti), metode penghancuran () dipanggil.


30
2018-02-22 12:54



Sesi- Apa yang dikatakan Chris Thompson.

Instansiasi - servlet adalah contoh ketika kontainer menerima permintaan pertama yang dipetakan ke servlet (kecuali servlet dikonfigurasi untuk memuat saat startup dengan <load-on-startup> elemen dalam web.xml). Instance yang sama digunakan untuk melayani permintaan berikutnya.


20
2018-06-24 00:27



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):

Kontainer servlet dapat mengirim permintaan bersamaan melalui layanan   metode servlet. Untuk menangani permintaan, Pengembang Servlet   harus membuat ketentuan yang memadai untuk pemrosesan bersamaan dengan beberapa   benang dalam metode layanan.

Meskipun tidak disarankan, alternatif untuk Pengembang adalah   mengimplementasikan antarmuka SingleThreadModel yang membutuhkan wadah   untuk menjamin bahwa hanya ada satu utas permintaan dalam satu waktu di   metode layanan. Wadah servlet dapat memenuhi persyaratan ini dengan   permintaan serialisasi pada servlet, atau dengan mempertahankan kolam servlet   contoh. Jika servlet adalah bagian dari aplikasi Web yang telah ada   ditandai sebagai didistribusikan, wadah dapat mempertahankan kolam servlet   contoh di setiap JVM bahwa aplikasi didistribusikan di seluruh.

Untuk servlet tidak mengimplementasikan antarmuka SingleThreadModel, jika   metode layanan (atau metode seperti doGet atau doPost yang   dikirim ke metode layanan kelas abstrak HttpServlet)   telah didefinisikan dengan kata kunci tersinkronisasi, wadah servlet   tidak dapat menggunakan pendekatan kumpulan instance, tetapi harus membuat serial permintaan   melewatinya. Sangat disarankan agar Pengembang tidak melakukan sinkronisasi   metode layanan (atau metode yang dikirimkan ke sana) dalam ini   keadaan karena efek merugikan pada kinerja


13
2018-03-05 11:41



Tidak. Servlet adalah tidak aman Thread

Ini memungkinkan mengakses lebih dari satu utas sekaligus

jika Anda ingin menjadikannya Servlet sebagai Thread aman., U dapat pergi

Implement SingleThreadInterface(i)  yang merupakan Antarmuka kosong tidak ada

metode

atau kita bisa pergi untuk metode sinkronisasi

kita dapat membuat metode layanan keseluruhan disinkronkan dengan menggunakan sinkronisasi

keword di depan metode

Contoh::

public Synchronized class service(ServletRequest request,ServletResponse response)throws ServletException,IOException

atau kita dapat menempatkan blok kode di blok Synchronized

Contoh::

Synchronized(Object)

{

----Instructions-----

}

Saya merasa bahwa blok Synchronized lebih baik daripada membuat keseluruhan metode

Disinkronkan


0
2018-04-14 15:32