You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将根路径下的404 URL映射到指定Servlet(Tomcat 8.5)

Hey there! Let's break down how to solve this Tomcat 8.5 mapping problem exactly as you need it. We'll start with the ideal solution that targets only root-level unknown URLs, then cover the fallback approach if that doesn't fit your setup.


This uses Tomcat's error page mechanism to intercept 404s only for root-level paths and route them to your UnhandledUrlsServlet, while leaving deeper paths to return the default 404.

Step 1: Configure Error Page Forwarding

Add this to your web.xml to send 404 errors to your servlet:

<error-page>
    <error-code>404</error-code>
    <location>/UnhandledUrlsServlet</location>
</error-page>

Step 2: Map Your Servlet

Set up your servlet with an exact mapping so it only responds to the error forward (not direct requests unless you want it to):

<servlet>
    <servlet-name>UnhandledUrlsServlet</servlet-name>
    <servlet-class>com.yourpackage.UnhandledUrlsServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>UnhandledUrlsServlet</servlet-name>
    <url-pattern>/UnhandledUrlsServlet</url-pattern>
</servlet-mapping>

Step 3: Add Path Logic to the Servlet

In your servlet's doGet/doPost methods, grab the original request URI (since the error forward changes the URI) and check if it's a root-level path:

// Get the original URL that triggered the 404
String originalUri = (String) request.getAttribute("javax.servlet.error.request_uri");
// Strip off the context path (skip this if your app is deployed at root)
String path = originalUri.substring(request.getContextPath().length());

// Split the path to check its depth
String[] pathSegments = path.split("/");
// Root-level paths like "/unknownUrl1" split into ["", "unknownUrl1"] (length 2)
if (pathSegments.length == 2 && !path.equals("/")) {
    // Your logic to handle the unhandled root-level URL
    response.getWriter().write("Handling unhandled root URL: " + path);
} else {
    // Deeper path? Send back the default 404
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
}

Now when someone hits /unknownUrl1 (no existing servlet/resource matches, so 404 is triggered), your servlet takes over. But /unknown/somethingElse will still return Tomcat's default 404 page.


Solution 2: Fallback - Catch All Requests and Filter Manually

If the error page approach doesn't work for your setup, you can map your servlet to catch all requests, then filter out which ones to handle.

Step 1: Map Servlet to All Requests

Add this to web.xml—note this will override all other servlet mappings, so you'll need to exclude known paths manually:

<servlet>
    <servlet-name>UnhandledUrlsServlet</servlet-name>
    <servlet-class>com.yourpackage.UnhandledUrlsServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>UnhandledUrlsServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Step 2: Filter Paths in the Servlet

In your servlet, first exclude any paths that already have handlers (like APIs, static resources, or other servlets), then check for root-level unknown paths:

String path = request.getRequestURI().substring(request.getContextPath().length());

// List of paths that already have existing handlers
List<String> handledPaths = Arrays.asList("/api", "/static", "/existing-servlet");
boolean isKnownPath = handledPaths.stream().anyMatch(path::startsWith);

// Forward known paths to their normal handlers
if (isKnownPath) {
    request.getRequestDispatcher(path).forward(request, response);
    return;
}

// Check if it's a root-level unknown path
String[] pathSegments = path.split("/");
if (pathSegments.length == 2 && !path.equals("/")) {
    // Handle the root-level unhandled URL
    response.getWriter().write("Handling unhandled root URL: " + path);
} else {
    // Return default 404 for deeper paths
    response.sendError(HttpServletResponse.SC_NOT_FOUND);
}

The downside here is you'll need to keep the handledPaths list updated as you add new servlets or resources, but it's a solid fallback if you need more direct control.


Quick Notes

  • If your app is deployed at a non-root context (like /myapp), make sure you always strip the context path when checking paths—otherwise your logic will break.
  • Tomcat 8.5 prioritizes exact servlet mappings over wildcard mappings, so any exact paths you have set up will still work even with the /* mapping in Solution 2.
  • Test thoroughly to make sure existing resources/servlets aren't being accidentally intercepted!

内容的提问来源于stack exchange,提问作者MTilsted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:25:37