Keywords: Servlet | URL Pattern | Web Development
Abstract: This article provides an in-depth exploration of the core differences between URL patterns / and /* in Servlet mapping, analyzing their impact on request handling mechanisms. By comparing the global override nature of /* with the default Servlet replacement function of /, it explains why both are generally unsuitable for direct Servlet mapping. The paper details the role of the empty string URL pattern and offers best practices for front controllers and static resource management, including the use of specific patterns like *.html or /app/*, and resource access control via Filters.
In Java Web development, configuring URL patterns for Servlets is fundamental to request routing, yet the distinction between <url-pattern>/*</url-pattern> and <url-pattern>/</url-pattern> often causes confusion. Understanding the behavior of these patterns is crucial for building efficient and maintainable web applications.
Global Override Pattern: /*
The <url-pattern>/*</url-pattern> is a globally overriding pattern. When a Servlet is configured with this pattern, it intercepts all requests entering the application context, including those that would otherwise be handled by other Servlets, such as the default Servlet or JSP Servlet. This means that regardless of the request path, e.g., http://host:port/context/hello or http://host:port/context/hello.jsp, the request is routed to this Servlet. This behavior is generally undesirable as it disrupts built-in Servlet container functionalities like static resource serving or JSP processing. Therefore, /* should primarily be used for Filters, not Servlets. Filters can pass requests to more specific Servlets by calling FilterChain#doFilter(), maintaining flexibility.
Default Servlet Replacement Pattern: /
In contrast, <url-pattern>/</url-pattern> does not override other registered Servlets. It only replaces the Servlet container's built-in default Servlet to handle all requests that do not match any other Servlet. This typically includes static resources (e.g., CSS, JS, image files) and directory listings. The default Servlet also manages advanced features like HTTP caching, media streaming, and file download resumption. Overriding the default Servlet requires developers to manually implement these tasks, which can be complex and error-prone. For instance, the JSF utility library OmniFaces provides an open-source example, FileServlet, to demonstrate proper static resource handling. As for why JSP requests (e.g., http://host:port/context/hello.jsp) are not processed by this pattern, it is because the JSP Servlet is default-mapped to the more specific pattern *.jsp, taking precedence over /.
Empty String URL Pattern:
Beyond / and /*, the empty string URL pattern <url-pattern></url-pattern> is noteworthy. It is invoked only when the application root path is requested (e.g., http://host:port/context), differing from <welcome-file>, which may trigger subfolder requests. This makes it ideal for implementing a "home page Servlet," although its logic may counterintuitively contrast with / handling unmatched requests.
Front Controller and Best Practices
For scenarios requiring a front controller, avoid using / or /* and opt for more specific URL patterns. For example, patterns like *.html, *.do, /pages/*, or /app/* allow precise control over request routing. Concurrently, static resources should be managed via independent patterns such as /resources/* or /static/*, aided by Filters to prevent processing by the front controller. Frameworks like Spring MVC include built-in static resource Servlets, enabling front controller mapping to / if resource URL patterns are configured. In summary, judicious selection of URL patterns enhances application maintainability and performance.