LEARN APACHE TOMCAT DEEP DIVE
Learn Apache Tomcat: From Zero to Servlet Container Master
Goal: Deeply understand the Apache Tomcat servlet container—from the Servlet and JSP specifications to its core architecture, security, and advanced features.
Why Learn Apache Tomcat?
Apache Tomcat is the most widely used Java web server and servlet container in the world. It powers countless applications, from small websites to large enterprise systems. Understanding Tomcat is not just about deploying a .war file; it’s about understanding the foundation of the Java web ecosystem.
After completing these projects, you will:
- Understand the Java Servlet lifecycle inside and out.
- Master JSP for dynamic view generation.
- Configure and tune Tomcat for production environments.
- Grasp Tomcat’s architecture: Catalina, Coyote, and Jasper.
- Implement custom components like Valves and Realms to extend Tomcat’s functionality.
- Be able to build and debug complex Java web applications with confidence.
Core Concept Analysis
1. The Servlet Container Model
Tomcat is a Servlet Container. It manages the lifecycle of Java objects called Servlets, which handle HTTP requests.
┌──────────────────────────┐ ┌───────────────────────────┐ ┌──────────────────────────┐
│ Web Browser │ │ Apache Tomcat │ │ Your Web App │
│ │ │ │ │ │
│ GET /hello HTTP/1.1 │─────▶│ Coyote (HTTP Connector) │─────▶│ Catalina (The Engine) │
│ │ │ Parses Request │ │ │
└──────────────────────────┘ │ │ │ Finds correct... │
│ │ │ Servlet │
│ │ │ │ │
│ │ │ ▼ │
│ │ │ ┌──────────────────┐ │
│ │ │ │ Your Servlet │ │
│ │ │ │ doGet(req,res) │ │
│ │ │ └──────────────────┘ │
│ Generates Response │ │ │
│ │ │ │
◀─────────────────────────────│ │◀─────│ │
HTTP/1.1 200 OK │ │ │ │
"Hello, World!" │ │ │ │
└───────────────────────────┘ └──────────────────────────┘
2. Core Components
- Catalina: The servlet container itself. The core engine that implements the Servlet specification, managing servlets, requests, and responses.
- Coyote: The Connector. It listens for HTTP requests on a specific port and forwards them to Catalina. It’s the bridge between the raw network socket and your Java code.
- Jasper: The JSP Engine. It parses
.jspfiles and compiles them into executable Java Servlets on the fly.
3. Configuration Hierarchy (server.xml)
Tomcat’s configuration is hierarchical and defined primarily in conf/server.xml.
<Server>
<Service>
<Connector port="8080" protocol="HTTP/1.1" />
<Engine>
<Host name="localhost" appBase="webapps">
<Context path="/my-app" docBase="my-app.war">
<!-- Your Web App's Specific Config -->
</Context>
<Valve className="org.apache.catalina.valves.AccessLogValve" />
</Host>
</Engine>
</Service>
</Server>
- Server: The entire Tomcat instance.
- Service: A grouping of Connectors and a single Engine.
- Connector: Defines how Tomcat receives requests (e.g., HTTP on port 8080).
- Engine: The request processing pipeline for a Service.
- Host: A virtual host (like
localhostoryourdomain.com). - Context: A single web application.
- Valve: A component that intercepts requests in the processing pipeline, like an access log recorder.
4. The Web Application (web.xml and programmatic)
Each web application is a Context. Its behavior is defined by the Servlet Specification, traditionally configured in a WEB-INF/web.xml file.
- Servlet Declarations:
<servlet> - Servlet Mappings:
<servlet-mapping>(maps a URL pattern to a servlet) - Filters: Intercept requests and responses.
- Listeners: React to application lifecycle events (e.g., startup, shutdown).
- Modern Approach: Since Servlet 3.0, you can do all of this programmatically with annotations (
@WebServlet) and programmatic configuration.
5. ClassLoading
Tomcat has a complex classloader hierarchy to isolate web applications from each other. This is crucial but can be a source of confusion.
Bootstrap (JRE classes)
|
System (Tomcat's own classes)
|
Common (Shared libraries for all webapps)
|
WebApp1 (Your app's classes in WEB-INF/classes and WEB-INF/lib)
|
WebApp2 (Isolated from WebApp1)
Project List
The following 10 projects will guide you from basic web app development to deeply understanding Tomcat’s internal workings.
Project 1: The Classic Servlet & JSP Guestbook
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java
- Alternative Programming Languages: Groovy, Kotlin (on the JVM)
- Coolness Level: Level 2: Practical but Forgettable
- Business Potential: 1. The “Resume Gold”
- Difficulty: Level 1: Beginner
- Knowledge Area: Java Servlets, JSP, Web Fundamentals
- Software or Tool: Apache Tomcat, Maven/Gradle
- Main Book: “Head First Servlets & JSP, 2nd Edition” by Bryan Basham, Kathy Sierra, Bert Bates
What you’ll build: A simple web application where users can post messages to a public guestbook. The form submission will be handled by a Servlet, and the messages will be displayed using a JSP.
Why it teaches Tomcat: This is the “Hello, World!” of Java web development. It forces you to understand the most fundamental concepts: the servlet lifecycle, request dispatching, form handling, and the relationship between Servlets (controllers) and JSPs (views).
Core challenges you’ll face:
- Creating a Servlet → maps to understanding
HttpServlet,doGet(), anddoPost() - Configuring
web.xml→ maps to mapping a URL path to your servlet class - Passing data from Servlet to JSP → maps to using
RequestDispatcherand setting request attributes - Displaying dynamic data in a JSP → maps to using scriptlets (
<% %>) and expressions (<%= %>)
Key Concepts:
- Servlet Lifecycle: “Head First Servlets & JSP” Chapter 3
- web.xml descriptor: “Head First Servlets & JSP” Chapter 4
- Model-View-Controller (MVC): “Head First Servlets & JSP” Chapter 2
- JSP Scripting Elements: Oracle JSP Docs
Difficulty: Beginner Time estimate: Weekend Prerequisites: Basic Java knowledge, familiarity with the command line.
Real world outcome: You will have a functional web application running on your local Tomcat server. You can access it in your browser, submit a form, and see the content update immediately. This provides a tangible result and a foundation for all future Java web projects.
Implementation Hints:
- Servlet Logic:
- In
doGet(), forward the request to yourguestbook.jspfile. - In
doPost(), retrieve the submitted message from theHttpServletRequestparameters. - Store the messages in a simple
ArrayListheld in theServletContext(application scope) for this basic version. - After adding a new message, use a redirect (
response.sendRedirect()) back to the guestbook page to prevent duplicate form submissions.
- In
- JSP Logic:
- Create a simple HTML form that
POSTs to your servlet’s URL. - Use a scriptlet to retrieve the list of messages from the application scope.
- Loop through the list and print each message.
- Create a simple HTML form that
Learning milestones:
- Servlet responds to a GET request → You understand the basic servlet lifecycle and URL mapping.
- Form submission is processed by the Servlet → You can handle POST requests and read parameters.
- Data is displayed dynamically on the JSP → You understand how to pass data from the backend to the frontend.
- Application state persists between requests → You grasp the concept of application scope.
Project 2: Build a Custom Request Logging Valve
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java
- Alternative Programming Languages: N/A
- Coolness Level: Level 3: Genuinely Clever
- Business Potential: 1. The “Resume Gold”
- Difficulty: Level 2: Intermediate
- Knowledge Area: Tomcat Architecture, Request Pipeline
- Software or Tool: Apache Tomcat
- Main Book: “Tomcat: The Definitive Guide, 2nd Edition” by Jason Brittain & Ian F. Darwin
What you’ll build: A custom Tomcat Valve that intercepts every incoming request to log the URL, processing time, and response status to a file.
Why it teaches Tomcat: This project pulls back the curtain on Tomcat’s internal request processing pipeline. You’ll learn that Tomcat is more than just a servlet runner; it’s an extensible framework of components. You’ll see how to add your own functionality directly into the server itself.
Core challenges you’ll face:
- Extending the
ValveBaseclass → maps to understanding the Valve contract and itsinvokemethod - Compiling and packaging the Valve → maps to creating a JAR file and placing it in Tomcat’s
libdirectory - Configuring the Valve in
server.xml→ maps to understanding how to insert your component into theHostorEnginepipeline - Measuring request time accurately → maps to the importance of calling
getNext().invoke(request, response)
Key Concepts:
- Tomcat Pipeline and Valves: “Tomcat: The Definitive Guide” Chapter 9
- server.xml configuration: Official Tomcat Documentation on
server.xml - Java Classloading: How Tomcat finds your Valve class from its
libdirectory.
Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1, basic understanding of Java project builds (JARs).
Real world outcome:
After configuring your Valve, you’ll see a new log file appear in your Tomcat’s logs directory. For every request you make to any web app on the server, a new line will be appended with details like [2025-12-20 14:30:00] GET /my-app/index.jsp - 200 OK (15ms). This provides a powerful, real-time debugging and monitoring tool that you built yourself.
Implementation Hints:
- Your Valve class must extend
org.apache.catalina.valves.ValveBase. - The core logic goes into the
invoke(Request request, Response response)method. - The
invokemethod is a chain of responsibility. You must callgetNext().invoke(request, response)to pass the request down the pipeline. - To measure time, record
System.currentTimeMillis()before callinggetNext().invoke()and after it returns. The difference is the processing time. - You can get the response status from the
response.getStatus()method. - Place your compiled JAR file in
$CATALINA_HOME/lib. - Add your valve to
server.xmlinside a<Host>or<Engine>element:<Valve className="com.mycompany.MyLoggingValve" />.
Learning milestones:
- Valve loads without errors on Tomcat startup → You’ve correctly packaged and deployed a custom server component.
- Basic request info is logged → You understand how to access request and response objects within the pipeline.
- Accurate timing is logged → You understand the chain-of-responsibility pattern.
- The Valve can be configured with parameters → You’ve learned how to make your server components configurable from
server.xml.
Project 3: A Webapp without web.xml
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java
- Alternative Programming Languages: Kotlin, Groovy
- Coolness Level: Level 3: Genuinely Clever
- Business Potential: 1. The “Resume Gold”
- Difficulty: Level 2: Intermediate
- Knowledge Area: Modern Servlet API (Servlet 3.0+)
- Software or Tool: Apache Tomcat 7+
- Main Book: “Java EE 7: The Big Picture” by Dr. Danny Coward
What you’ll build: A complete web application (like the Guestbook from Project 1) that is configured entirely through Java code, with no web.xml file at all.
Why it teaches Tomcat: This project teaches the modern way of building Java web applications. You’ll learn that Tomcat (since version 7) supports the Servlet 3.0 specification, which allows for programmatic configuration. This reduces “XML hell” and keeps configuration closer to the code it affects.
Core challenges you’ll face:
- Using the
@WebServletannotation → maps to replacing<servlet>and<servlet-mapping>tags - Implementing a
ServletContextListener→ maps to getting a hook into the application’s startup phase - Programmatically adding Filters and other Servlets → maps to using the
ServletContextobject to build your application pipeline in code - Understanding the web application startup sequence → maps to how Tomcat discovers and runs your listener
Key Concepts:
- Servlet 3.0 Annotations:
@WebServlet,@WebFilter,@WebListener(Baeldung Tutorial) - Programmatic Configuration: Official Oracle Java EE Tutorial on the topic.
ServletContextListener: “Head First Servlets & JSP” Chapter 10
Difficulty: Intermediate Time estimate: 1-2 days Prerequisites: Project 1, understanding of Java Annotations.
Real world outcome: You’ll have a clean, modern web application project. The entire configuration is co-located with your Java code, making it easier to read, refactor, and maintain. This is how many modern Java frameworks like Spring Boot build on top of the Servlet ecosystem.
Implementation Hints:
- To replace a
<servlet>and<servlet-mapping>, simply add@WebServlet("/your/url")to your servlet class. - Create a class that implements
ServletContextListener. - Annotate this class with
@WebListener. - Tomcat will automatically find this listener and run its
contextInitialized()method on startup. - Inside
contextInitialized(ServletContextEvent sce), you can get theServletContextobject viasce.getServletContext(). - Use methods like
servletContext.addServlet(...)andservletContext.addFilter(...)to build up your application dynamically. This is useful for more complex scenarios not handled by simple annotations.
Learning milestones:
- A servlet is accessible via an
@WebServletannotation → You’ve successfully replacedweb.xmlfor simple cases. - A
@WebListenerruns code on application startup → You understand the entry point for programmatic configuration. - A Filter is added programmatically and intercepts requests → You can build a complete, dynamic pipeline in Java.
- Your application runs correctly with an empty (or no)
web.xml→ You have mastered modern, XML-free web app configuration.
Project 4: Configure a JNDI Database Connection Pool
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java
- Alternative Programming Languages: N/A
- Coolness Level: Level 1: Pure Corporate Snoozefest
- Business Potential: 1. The “Resume Gold”
- Difficulty: Level 2: Intermediate
- Knowledge Area: JNDI, Database Connectivity, Resource Management
- Software or Tool: Apache Tomcat, a database like H2 or PostgreSQL
- Main Book: “Tomcat: The Definitive Guide, 2nd Edition” by Jason Brittain & Ian F. Darwin
What you’ll build: A servlet that performs a database query by looking up a DataSource from Tomcat’s JNDI context, instead of creating the database connection itself.
Why it teaches Tomcat: This project teaches a critical skill for enterprise Java development: decoupling your application from resource configuration. You’ll learn how to let Tomcat manage a pool of database connections, which is far more efficient and robust than managing them in your application code. This is a key feature of a real application server.
Core challenges you’ll face:
- Configuring a
Resourceincontext.xml→ maps to telling Tomcat how to connect to the database (URL, user, pass, driver) - Adding the JDBC driver JAR → maps to making the database driver available to Tomcat’s classloader
- Using JNDI to look up the
DataSource→ maps to theInitialContextandlookup("java:comp/env/...")pattern - Linking the resource in
web.xml→ maps to the<resource-ref>tag that connects your code to the server’s resource
Key Concepts:
- JNDI (Java Naming and Directory Interface): What it is and why it’s used for resource lookups.
- Connection Pooling: Why it’s critical for performance. (Baeldung on HikariCP is a great explanation).
- Tomcat JNDI Resources HOW-TO: Official Tomcat Documentation.
context.xmlvsserver.xml: Where to place environment-specific configuration.
Difficulty: Intermediate Time estimate: 1-2 days Prerequisites: Project 1, basic SQL knowledge.
Real world outcome:
Your application code will be cleaner and more portable. It will no longer contain database credentials. You can move the application from a development to a production environment just by changing the context.xml file, without touching your code. You can monitor the connection pool in Tomcat’s Manager App, seeing active and idle connections.
Implementation Hints:
- Download a JDBC driver (e.g., for PostgreSQL) and place the JAR in
$CATALINA_HOME/lib. - Define the JNDI resource in your webapp’s
META-INF/context.xml. This is the preferred location.<Context> <Resource name="jdbc/myDB" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="dbuser" password="dbpassword" driverClassName="org.postgresql.Driver" url="jdbc:postgresql://localhost:5432/mydatabase"/> </Context> - In your
web.xml, add a resource reference:<resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/myDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> - In your servlet code, look up the DataSource:
Context initContext = new InitialContext(); Context envContext = (Context)initContext.lookup("java:comp/env"); DataSource ds = (DataSource)envContext.lookup("jdbc/myDB"); Connection conn = ds.getConnection(); // ... use the connection ...
Learning milestones:
- Tomcat starts without JNDI errors → Your
context.xmlis correct and the JDBC driver is found. - Servlet successfully looks up the DataSource → Your JNDI lookup code and
web.xmlreference are correct. - Database query succeeds → The entire chain, from servlet to Tomcat to the database, is working.
- You can see the connection pool stats in the Manager App → You have tangible proof that Tomcat is managing the resource pool.
Project 5: Implement a Custom Security Realm
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java
- Alternative Programming Languages: N/A
- Coolness Level: Level 4: Hardcore Tech Flex
- Business Potential: 2. The “Micro-SaaS / Pro Tool”
- Difficulty: Level 3: Advanced
- Knowledge Area: Java EE Security, Tomcat Architecture, Authentication
- Software or Tool: Apache Tomcat
- Main Book: “Java EE Security for Architects” by Tomitribe
What you’ll build: A custom Tomcat Realm that authenticates users against a simple properties file (users.properties) and assigns them roles. You will then use this Realm to protect a web application.
Why it teaches Tomcat: This project dives deep into Tomcat’s security architecture. You’ll replace one of Tomcat’s core pluggable components. You’ll learn how Tomcat separates security policy (who can access what) from security mechanism (how users are authenticated).
Core challenges you’ll face:
- Extending
RealmBase→ maps to implementing theauthenticate()andgetName()methods - Parsing a custom user store → maps to reading your
users.propertiesfile and caching credentials securely - Implementing the
authenticate()method → maps to validating passwords and returning aGenericPrincipalwith correct roles - Configuring
server.xmlandweb.xml→ maps to telling Tomcat to use your Realm and defining protected resources
Key Concepts:
- Tomcat Realms: Official Tomcat Documentation on Realms.
- Java EE Declarative Security: Using
web.xmlto define security constraints, login methods, and roles. - Principal and Authentication: The core objects representing a user and the process of verifying them.
Difficulty: Advanced Time estimate: 1-2 weeks Prerequisites: Project 2 and 4, solid understanding of Java.
Real world outcome: You’ll be able to protect a page in your web app. When an unauthenticated user tries to access it, they will be redirected to a login form. After authenticating against your custom Realm, they will be granted access. You’ll have built a fundamental component for any serious application.
Implementation Hints:
- Your Realm class must extend
org.apache.catalina.realm.RealmBase. - The most important method is
authenticate(String username, String credentials). In it, you’ll look up the user in your properties file. If the password matches, you return aGenericPrincipalobject containing the username and a list of their roles. - You also need to implement
getPrincipal(String username). - Package your Realm as a JAR and place it in
$CATALINA_HOME/lib. - In
server.xml, configure your Realm inside the<Host>or<Engine>:<Realm className="com.mycompany.MyCustomRealm" userFile="/path/to/users.properties" /> - In your web app’s
web.xml, define the security constraint:<security-constraint> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>administrator</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/login-error.jsp</form-error-page> </form-login-config> </login-config> <security-role> <role-name>administrator</role-name> </security-role>
Learning milestones:
- Tomcat loads your Realm on startup → Packaging and
server.xmlconfiguration are correct. - Unauthenticated access to a protected URL is blocked → The security constraint in
web.xmlis working. - A user can log in successfully via a form → Your
authenticatemethod works correctly. - A user with the wrong role is denied access → Your role handling and
GenericPrincipalcreation are correct.
Project 6: A Real-time Chat App with WebSockets
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java, JavaScript
- Alternative Programming Languages: N/A
- Coolness Level: Level 3: Genuinely Clever
- Business Potential: 2. The “Micro-SaaS / Pro Tool”
- Difficulty: Level 2: Intermediate
- Knowledge Area: WebSockets, Asynchronous Communication
- Software or Tool: Apache Tomcat 7+
- Main Book: “Java WebSocket Programming” by Danny Coward
What you’ll build: A simple web-based chat room where multiple users can connect and exchange messages in real-time, powered by Tomcat’s native WebSocket support.
Why it teaches Tomcat: This project teaches you how Tomcat handles persistent, stateful connections beyond the simple request-response model of HTTP. You will learn how to manage the lifecycle of WebSocket connections and broadcast messages to multiple clients efficiently.
Core challenges you’ll face:
- Creating a WebSocket Endpoint → maps to using the
@ServerEndpointannotation and implementing lifecycle methods like@OnOpen,@OnMessage,@OnClose - Managing Client Sessions → maps to keeping a collection of active
Sessionobjects to broadcast messages to - Handling Concurrency → maps to ensuring your collection of sessions is accessed in a thread-safe manner
- Writing the JavaScript client → maps to using the browser’s
WebSocketAPI to connect to your endpoint and exchange messages
Key Concepts:
- Java API for WebSocket (JSR 356): The standard API implemented by Tomcat.
- WebSocket Lifecycle: The
@OnOpen,@OnMessage,@OnClose,@OnErrorevents. - Session Management: Tracking connected clients.
- Broadcasting: Sending a message to all connected clients.
Difficulty: Intermediate Time estimate: Weekend Prerequisites: Project 1, basic JavaScript.
Real world outcome: You’ll have a functioning real-time chat application. When you open the chat page in two different browser windows, messages typed in one will instantly appear in the other. This demonstrates a powerful, modern web capability and your ability to implement it.
Implementation Hints:
- Create a Java class and annotate it with
@ServerEndpoint("/chat"). - This class is a singleton by default. You need a static, thread-safe collection (like
Collections.synchronizedSet(new HashSet<>())) to storeSessionobjects. - In the
@OnOpenmethod, add the newSessionto your collection. - In the
@OnClosemethod, remove theSessionfrom your collection. - In the
@OnMessagemethod, iterate over your collection of sessions and usesession.getBasicRemote().sendText(message)to broadcast the received message to every connected client. Be mindful of concurrency issues here. - The client-side JavaScript is simple:
const socket = new WebSocket("ws://localhost:8080/your-app/chat"); socket.onmessage = function(event) { // append event.data to your chat log }; function sendMessage() { socket.send(message); }
Learning milestones:
- JavaScript client successfully connects to the Java endpoint → Your
@ServerEndpointis correctly deployed and configured. - Messages sent from the client are received by the server → Your
@OnMessagemethod is working. - A message sent by one client is broadcast to all other clients → You have successfully implemented session management and broadcasting.
- The server correctly handles clients disconnecting → Your
@OnCloselogic is robust.
Project 7: Build a Tiny Servlet Container from Scratch
- File: LEARN_APACHE_TOMCAT_DEEP_DIVE.md
- Main Programming Language: Java
- Alternative Programming Languages: N/A
- Coolness Level: Level 5: Pure Magic (Super Cool)
- Business Potential: 1. The “Resume Gold”
- Difficulty: Level 4: Expert
- Knowledge Area: Networking, HTTP, Java Reflection, Classloading
- Software or Tool: Just a Java compiler and a dream.
- Main Book: “How Tomcat Works: A Guide to Developing Your Own Java Servlet Container” by Budi Kurniawan and Paul Deck
What you’ll build: A simple program that acts like Tomcat. It will open a server socket, listen for HTTP requests, parse them, and pass them to a hard-coded servlet. It will then take the servlet’s output and format it as a valid HTTP response.
Why it teaches Tomcat: This is the ultimate project for understanding Tomcat. By building a (very) simplified version of it, you demystify the entire process. You will finally understand what a “container” truly is: a program that manages the lifecycle of other programs according to a specific contract (the Servlet API).
Core challenges you’ll face:
- Opening a
ServerSocketand parsing raw HTTP → maps to implementing a miniature Coyote - Creating mock
HttpServletRequestandHttpServletResponseobjects → maps to understanding the Servlet API from the container’s perspective - Loading a servlet class using reflection → maps to dynamically loading and instantiating servlets
- Managing the servlet lifecycle → maps to calling
init()once andservice()for each request
Key Concepts:
- Socket Programming:
java.net.ServerSocketandjava.net.Socket. - HTTP/1.1 Protocol: The structure of a raw request and response (Request Line, Headers, Body).
- Java Reflection:
Class.forName(),newInstance(). - The Servlet API contract: The methods and objects a container must provide.
Difficulty: Expert Time estimate: 1-2 weeks Prerequisites: Project 1, strong Java skills, basic understanding of the HTTP protocol.
Real world outcome:
You will run a single Java main method. You can then open your web browser to http://localhost:8080 and see the output of a servlet you wrote, served by your own container. You’ve essentially built a micro-Tomcat.
Implementation Hints:
Phase 1: A Static Web Server
- Create a
mainmethod that opens aServerSocketon a port (e.g., 8080). - Create an infinite loop that calls
serverSocket.accept()to get aSocketfor each new connection. - For each
Socket, get itsInputStreamandOutputStream. - Read the first line of the
InputStream(the HTTP request line, e.g.,GET /index.html HTTP/1.1). - Based on the requested path, find a local file.
- Write a valid HTTP response to the
OutputStream(e.g.,HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n) followed by the file’s content.
Phase 2: Add Servlet Support
- Modify the request parsing. If the URL matches a servlet path (e.g.,
/servlet/MyServlet), don’t look for a file. - Create simple implementations of the
HttpServletRequestandHttpServletResponseinterfaces. You’ll need to parse headers and parameters from theInputStreamto populate your request object. - Use reflection (
Class.forName("com.mycompany.MyServlet").newInstance()) to create an instance of the servlet. - Call its
service()method, passing your mock request and response objects. - After the
service()method returns, take the content written to your response object’s writer/stream and wrap it in an HTTP response.
Learning milestones:
- Your server can serve a static HTML file → You understand basic socket programming and the HTTP protocol.
- Your server can receive a request and instantiate the correct servlet → You’ve mastered reflection and request routing.
- The servlet can read request parameters and headers → Your
HttpServletRequestimplementation is working. - The servlet’s output is correctly displayed in the browser → Your
HttpServletResponseimplementation and response formatting are correct.
Summary of Projects
| Project | Main Language | Difficulty | Time Estimate | Core Concept Taught |
|---|---|---|---|---|
| 1. Classic Servlet & JSP Guestbook | Java | Beginner | Weekend | Servlet Lifecycle, JSP, web.xml |
| 2. Custom Request Logging Valve | Java | Intermediate | Weekend | Tomcat Pipeline, server.xml |
3. A Webapp without web.xml |
Java | Intermediate | 1-2 days | Servlet 3.0+ Programmatic API |
| 4. JNDI Database Connection Pool | Java | Intermediate | 1-2 days | JNDI, Resource Management, Connection Pools |
| 5. Implement a Custom Security Realm | Java | Advanced | 1-2 weeks | Tomcat Security, Authentication, Realms |
| 6. Real-time Chat App with WebSockets | Java, JavaScript | Intermediate | Weekend | WebSockets, Asynchronous Communication |
| 7. Build a Tiny Servlet Container | Java | Expert | 1-2 weeks | The entire container model from scratch |
I recommend starting with Project 1: The Classic Servlet & JSP Guestbook. It’s the quintessential starting point that covers 80% of what you’ll do in day-to-day Java web development and builds the foundation needed for all the other projects. After that, move to Project 3: A Webapp without web.xml to modernize your knowledge before tackling more advanced topics like Valves and Realms. Good luck!