How does a Web Servers Work?

Today the line between “app server” and “web server” is fuzzy. But people continue to use the terms differently, primarily for emphasis.

We often wonder how a web container/ web server (e.g., tomcat or jboss) work? How do they handle the incoming HTTP requests from all over the world? What are the things that make it happen behind the scenes? How java servlet API (i.e. classes like ServletContext, ServletRequest, ServletResponse and Session) fit into picture?

These are very important questions/concepts you must know if you are a web application developer or aspire to be. In this post, I will try to find answers to some of the above questions, if not all. Remain concentrated from here.

1. What is the Difference between a Web server, Application server, and Web container?

I will first talk about web servers and application servers. Let me say it in one-liner:

Historically they were different, but these two previously distinct categories slowly merged, and now should be seen as one entity in most of the cases and uses.

In early days of the Mosaic browser (often described as the first graphical web browser) and hyper-linked content, there evolved a new concept “web server” that served static web page content and images over HTTP protocol. Simple enough.

In these days, most of the content was static, and the HTTP 1.0 protocol was just a way to ship files around. Soon, however, the web servers evolved to have CGI capabilities. It means effectively launching a process on each web request to generate dynamic content.

By this time, HTTP protocol also matured and web servers became more sophisticated with additional functionality like caching, security, and session management. As the technology further matured, we got company-specific java-based server-side technology from Kiva and NetDynamics, which eventually all merged into JSP (java server pages), which we still use in most applications development today.

web server application server

This was about web servers. Now, let’s talk about application servers.

In a parallel category, the application servers have evolved and existed for a long time. Some companies delivered products for Unix like Tuxedo (transaction-oriented middleware), TopEnd, Encina that were philosophically derived from Mainframe application management and monitoring environments like IMS and CICS.

Most of these products specified “closed” product-specific communications protocols to interconnect “fat” clients to servers. In 90’s, these traditional app server products began to embed basic HTTP communication capability, at first via gateways. Soon, the lines started to blur between these two categories.

By the time web servers became more mature with respect to handling higher loads, more concurrency, and better features, application servers started delivering more HTTP-based communication capability. All this resulted in a very thin line between web servers and application servers.

At this point, the line between “app server” and “web server” is fuzzy. But people continue to use the terms differently, primarily for emphasis.

When someone says “web server” you often think HTTP-centric, web UI oriented applications. When someone says “Application server” you may think “heavier loads, enterprise features, transactions and queuing, multi-channel communication (HTTP + more)”. But mostly it is the same product that serves both sets of requirements now-a-days.

That’s all about web servers and application servers. Now move towards third term i.e. web container.

web server servlet container

Web container, specially in java, should be refer to servlet container. A servlet container is a web server component that interacts with Java servlets. A web container is responsible for managing the life-cycle of servlets, mapping a URL to a particular servlet, and ensuring that the URL requester has the correct access rights, among many other services. Putting together all the above facts, the servlet container is the runtime environment where your servlet runs and its life cycle is maintained.

2. What are Servlets? How do they help?

In Java, servlets enable you to write server-side components that help generate dynamic content based on requests. Factually, a Servlet is an interface defined in the java.servlet package. It declares three essential methods for a servlet’s life cycle: init(), service(), and destroy(). These methods are implemented by every servlet(either defined in SDK or user-defined) and invoked at specific times by the server during its life cycle.

Servlet classes are loaded to the container by its class loader dynamically, either through lazy loading or eager loading. Each request is in its own thread, and a servlet object can serve multiple threads at the same time. When it is no longer being used, it is garbage collected by JVM.

Lazy loading servlet

Lazy Loaded Servlet1
Lazy Loaded Servlet

Eager loading servlet

Eagerly Loaded Servlet1
Eagerly Loaded Servlet

3. What is ServletContext? Who creates it?

When the servlet container starts up, it will deploy and load all web applications. When a web application gets loaded, the servlet container will create the ServletContext once per application and keep in server’s memory.

The webapp’s web.xml will be parsed and every Servlet, Filter and Listener found in web.xml will be created once and kept in server’s memory as well. When the servlet container shuts down, it will unload all web applications and the ServletContext and all Servlet, Filter and Listener instances will be trashed.

As per java docs, ServletContext defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file. In the case of a web application marked “distributed” in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won’t be truly global). Use an external resource like a database instead.

4. Where do ServletRequest and ServletResponse fit into the life cycle?

The servlet container is attached to a webserver which listens on HTTP requests on a certain port number, which is usually 80. When a client (user with a web-browser) sends a HTTP request, the servlet container will create new HttpServletRequest and HttpServletResponse objects and pass it through the methods of the already-created Filter and Servlet instances whose URL-pattern matches the request URL, all in the same thread.

The request object provides access to all information of the HTTP request, such as the request headers and the request body. The response object provides facility to control and send the HTTP response the way you want, such as setting headers and the body (usually with HTML content from a JSP file). When the HTTP response is committed and finished, then both the request and response objects will be trashed.

5. How is the Session managed? Know the cookie?

When a client visits the web-app for the first time and/or the HttpSession is to be obtained for the first time by request.getSession(), then the servlet container will create it, generate a long and unique ID (which you can get by session.getId()) and store it in server’s memory. The servlet container will also set a Cookie in the HTTP response with JSESSIONID as the cookie name and the unique session ID as the cookie value.

As per the HTTP cookie specification (a contract a decent web browser and webserver has to adhere), the client (the web browser) is required to send this cookie back in the subsequent requests as long as the cookie is valid. The servlet container will determine every incoming HTTP request header for the presence of the cookie with the name JSESSIONID and use its value to get the associated HttpSession from server’s memory.

The HttpSession lives until it has not been used for more than the time, a setting you can specify in web.xml, which defaults to 30 minutes. So when the client no longer visits the web application for over 30 minutes, the servlet container will trash the session. Every subsequent request, even though with the cookie specified, will not have access to the same session anymore. The servlet container will create a new one.

Existing Session

Existing session

New Session

New session

On the other hand, the session cookie on the client side has a default lifetime which is as long as the browser instance is running. So when the client closes the browser instance (all tabs/windows), then the session will be trashed at the client side. In a new browser instance the cookie associated with the session won’t be sent anymore. A new request.getSession() would return a brand new HttpSession and set a cookie with a brand new session ID.

6. How should thread-safety be ensured?

It would be best if you now had learned that Servlets and filters are shared among all requests. That’s the nice thing of Java, it’s multi-threaded and different threads (i.e. HTTP requests) can make use of the same instance. It would otherwise have been too expensive to recreate it on every request.

thread-safety

However, you should also realize that you should never assign any request or session scoped data as a servlet or filter instance variable. It will be shared among all other requests in other sessions. That’s thread-unsafe! The below example illustrates that:

public class MyServlet extends HttpServlet
{
  private Object thisIsNOTThreadSafe; //Don't to this
 
  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.
  }
}

Do not do this. It will result in a bug in the software.

Happy Learning !!

Recommended link(s):

http://www.invir.com/int-prog-cgi.html

Weekly Newsletter

Stay Up-to-Date with Our Weekly Updates. Right into Your Inbox.

Comments

Subscribe
Notify of
33 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.