java - How do servlets work? Instantiation, sessions, shared variables and multithreading -


suppose, have webserver holds numerous servlets. information passing among servlets setting session , instance variables.

now, if 2 or more users send request server happens session variables? common users or different each user. if different, how server able differentiate between different users?

one more similar question, if there n users accessing particular servlet, servlet gets instantiated first time first user accessed or instantiated users separately? in other words, happens instance variables?

servletcontext

when servlet container (like apache tomcat) starts up, deploy , load web applications. when web application loaded, servlet container creates servletcontext once , keeps in server's memory. web app's web.xml file parsed, , each <servlet>, <filter> , <listener> found (or each class annotated @webservlet, @webfilter , @weblistener respectively) instantiated once , kept in server's memory well. each instantiated filter, init() method invoked new filterconfig.

when servlet container shuts down, unloads web applications, invokes destroy() method of initialized servlets , filters, , servletcontext, servlet, filter , listener instances trashed.

when servlet has <servlet><load-on-startup> or @webservlet(loadonstartup) value greater 0, init() method invoked during startup new servletconfig. servlets initialized in same order specified value (1 -> 1st, 2 -> 2nd, etc). if same value specified more 1 servlet, each of servlets loaded in order appear in web.xml, or @webservlet classloading. in event "load-on-startup" value absent, init() method invoked whenever http request hits servlet first time.

httpservletrequest , httpservletresponse

the servlet container attached web server listens http requests on port number (port 8080 used during development , port 80 in production). when client (user web browser) sends http request, servlet container creates new httpservletrequest , httpservletresponse objects , passes them through defined filter chain and, eventually, servlet instance.

in case of filters, dofilter() method invoked. when code calls chain.dofilter(request, response), request , response continue on next filter, or hit servlet if there no remaining filters.

in case of servlets, service() method invoked. default, method determines 1 of doxxx() methods invoke based off of request.getmethod(). if determined method absent servlet, http 405 error returned in response.

the request object provides access of information http request, such headers , body. response object provides ability control , send http response way want by, instance, allowing set headers , body (usually generated html content jsp file). when http response committed , finished, both request , response objects recycled , made reuse.

httpsession

when client visits webapp first time and/or httpsession obtained first time via request.getsession(), servlet container creates new httpsession object, generates long , unique id (which can session.getid()), , store in server's memory. servlet container sets cookie in set-cookie header of http response jsessionid name , unique session id value.

as per http cookie specification (a contract decent web browser , web server have adhere to), client (the web browser) required send cookie in subsequent requests in cookie header long cookie valid (i.e. unique id must refer unexpired session , domain , path correct). using browser's built-in http traffic monitor, can verify cookie valid (press f12 in chrome / firefox 23+ / ie9+, , check net/network tab). servlet container check cookie header of every incoming http request presence of cookie name jsessionid , use value (the session id) associated httpsession server's memory.

the httpsession stays alive until has not been used more timeout value specified in <session-timeout>, setting in web.xml. timeout value defaults 30 minutes. so, when client doesn't visit web app longer time specified, servlet container trashes session. every subsequent request, cookie specified, not have access same session anymore; servlet container create new session.

on client side, session cookie stays alive long browser instance running. so, if client closes browser instance (all tabs/windows), session trashed on client's side. in new browser instance, cookie associated session wouldn't exist, no longer sent. causes entirely new httpsession created, entirely new session cookie begin used.

in nutshell

  • the servletcontext lives long web app lives. shared among all requests in all sessions.
  • the httpsession lives long client interacting web app same browser instance, , session hasn't timed out @ server side. shared among all requests in same session.
  • the httpservletrequest , httpservletresponse live time servlet receives http request client, until complete response (the web page) has arrived. not shared elsewhere.
  • all servlet, filter , listener instances live long web app lives. shared among all requests in all sessions.
  • any attribute defined in servletcontext, httpservletrequest , httpsession live long object in question lives. object represents "scope" in bean management frameworks such jsf, cdi, spring, etc. frameworks store scoped beans attribute of closest matching scope.

thread safety

that said, major concern possibly thread safety. should know servlets , filters shared among requests. that's nice thing of java, it's multithreaded , different threads (read: http requests) can make use of same instance. otherwise expensive recreate, init() , destroy() them every single request.

you should realize should never assign request or session scoped data instance variable of servlet or filter. shared among other requests in other sessions. that's not thread-safe! below example illustrates this:

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 requests!         thisisthreadsafe = request.getparameter("foo"); // ok, thread safe.     }  } 

see also:


Comments