Application Context Path Configuration
When deploying web applications through an IDE, the default access URL often includes the _war_exploded suffix. To create a cleaner URL path, you need to modify the Application Context setting.
The Application Context defines the web application's root path on the server. To change it, locate the deployment configuration panel and update the context field from /project_name_war_exploded to /project_name. After this modification, your application will be accessible at http://localhost:8080/project_name without the exploded archive suffix.
Understanding the Tomcat-Servlet Architecture
Servlet technology represents one of the three fundamental components in Java web development, alongside Filter and Listener. Tomcat functions as both a servlet container and runtime environment, where servlets act as the primary mechanism for processing web requests.
The container handles incoming HTTP connections, parses request data, and routes them to appropriate servlet instances based on URL pattern matching. Each servlet extends the Java Servlet API to produce dynamic content by processing client requests and constructing responses. Tomcat manages the complete lifecycle: class loading, instantiation, initialization via init(), request dispatching, and eventual destruction.
While modern development typically leverages higher-level frameworks like Spring MVC, understanding servlet mechanics remains crucial for grasping web application fundamentals and performing low-level customizations such as implementing specialized filters or listeners.
Implementing a Servlet Component
Step 1: Creating the Servlet Class
Generate a new servlet class that inherits from HttpServlet. Override the relevant methods such as doGet(), doPost(), doPut(), or doDelete() to handle specific HTTP verbs.
The HttpServlet base class automatically delegates to the appropriate doXxx() method based on the request method type.
package org.webapp.servlets;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class GreetingProcessor extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
try (PrintWriter outputWriter = resp.getWriter()) {
outputWriter.println("");
outputWriter.println("<html><head><title>Greeting</title></head><body>");
outputWriter.println("<h2>Welcome to Servlet Processing!</h2>");
outputWriter.println("<p>Current timestamp: " + System.currentTimeMillis() + "</p>");
outputWriter.println("</body></html>");
}
}
}
Step 2: Mapping the Servlet
Approach A: XML Configuration
Define servlet mapping in WEB-INF/web.xml:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>greeting-servlet</servlet-name>
<servlet-class>org.webapp.servlets.GreetingProcessor</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>greeting-servlet</servlet-name>
<url-pattern>/greeting</url-pattern>
</servlet-mapping>
</web-app>
This configuration routes all requests to /greeting to the GreetingProcessor class.
Approach B: Annotation-Based Configuration
For Servlet 3.0+ (Java EE 6+, Tomcat 8+), use the @WebServlet annotation:
@WebServlet(name = "greeting-servlet", urlPatterns = {"/greeting", "/welcome"})
public class GreetingProcessor extends HttpServlet {
// Implementation here
}
The container scans for annotated classes during deployment, eliminating the need for web.xml declarations.
The @WebServlet annotation supports multiple attributes:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {}; // Primary mapping attribute
int loadOnStartup() default -1;
WebInitParam[] initParams() default {};
boolean asyncSupported() default false;
String smallIcon() default "";
String largeIcon() default "";
String description() default "";
String displayName() default "";
}
URL Pattern Rules:
- Exact Match:
@WebServlet("/user/profile")matches only this precise path - Directory Match:
@WebServlet("/admin/*")matches all paths under/admin/ - Extension Match:
@WebServlet("*.action")matches any URL ending with.action
Note: Directory patterns must start with /. Extension patterns must NOT start with /.
Step 3: Deployement and Access
Launch Tomcat and access the servlet via:
http://localhost:8080/your-project-name/greeting
Request Processing Flow
- Client Request: The browser sends an HTTP request containing URL, method, headers, and body. For
http://localhost:8080/myapp/greeting, this resolves to: server (localhost:8080), application (myapp), and resource (/greetingmapping). - Server Reception: Tomcat's connector listens on the configured port, accepts the connection, and parses the raw HTTP data into request/response objects.
- Servlet Resolution: The container examines
web.xmlor annotations to locate the servlet matching the request URL. - Lifecycle Management: If no servlet instance exists, Tomcat loads the class, instantiates it using the default constructor, and invokes
init()for one-time initialization. - Service Invocation: The container calls
service(ServletRequest req, ServletResponse res), which internally dispatches todoGet(),doPost(), etc., based on the HTTP method. These methods interact with the request and response objects to process input and generate output. - Response Generation: The servlet writes content to the
ServletResponseoutput stream, including status codes, headers, and body content. - Response Transmission: Tomcat transforms the
ServletResponseinto a proper HTTP response and sends it back to the client. - Resource Cleanup: After completion, the container may return the servlet instance to a pool or, during shutdown, call
destroy()to release resources. Tomcat manages concurrent requests through a multi-threaded model, creating a new thread for each request while reusing servlet instances, making thread-safety considerations essential.