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

如何按路径指定Servlet错误页面?多语言404页面适配方案问询

解决同WAR下按区域路径返回本地化404页面的问题

根据你的需求,在不拆分WAR的前提下,有两种可靠的方案来实现按请求路径返回对应区域的404页面,我分别给你详细说明:

方案一:自定义错误处理Servlet(推荐,兼容所有Java EE版本)

这个方案利用容器的错误页面机制,先把所有404请求转发到一个自定义Servlet,再由Servlet根据原始请求路径判断区域,转发到对应本地化页面。

步骤1:配置web.xml

首先在web.xml里指定404错误的处理路径,并注册自定义Servlet:

<!-- 全局404错误指向自定义处理Servlet -->
<error-page>
    <error-code>404</error-code>
    <location>/locale-error-handler</location>
</error-page>

<!-- 注册错误处理Servlet -->
<servlet>
    <servlet-name>LocaleErrorHandler</servlet-name>
    <servlet-class>com.yourcompany.web.LocaleErrorHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>LocaleErrorHandler</servlet-name>
    <url-pattern>/locale-error-handler</url-pattern>
</servlet-mapping>

步骤2:编写错误处理Servlet

在Servlet中,我们可以通过容器提供的属性获取原始请求的URI,然后判断请求属于哪个区域,再转发到对应404页面:

package com.yourcompany.web;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class LocaleErrorHandlerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取引发404的原始请求路径
        String originalUri = (String) request.getAttribute("javax.servlet.error.request_uri");
        
        // 初始化请求转发器
        RequestDispatcher dispatcher;
        
        // 根据原始路径判断区域
        if (originalUri != null) {
            if (originalUri.startsWith("/a/")) {
                dispatcher = request.getRequestDispatcher("/a/404.html");
            } else if (originalUri.startsWith("/b/")) {
                dispatcher = request.getRequestDispatcher("/b/404.html");
            } else {
                // 处理不属于a/b区域的请求,返回默认404
                dispatcher = request.getRequestDispatcher("/default-404.html");
            }
        } else {
            // 极端情况:无法获取原始URI,返回默认页面
            dispatcher = request.getRequestDispatcher("/default-404.html");
        }
        
        // 转发到对应404页面
        dispatcher.forward(request, response);
    }
}

方案二:用Filter提前拦截不存在的资源

这个方案是在请求到达容器处理之前,先检查请求的资源是否存在,如果不存在,直接转发到对应区域的404页面,避免触发容器的默认404流程。

步骤1:编写Filter类

package com.yourcompany.web;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Locale404Filter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String requestUri = request.getRequestURI();
        ServletContext context = request.getServletContext();
        
        // 检查请求的静态资源是否存在(动态资源如Servlet映射建议交给容器处理)
        boolean resourceExists = false;
        try {
            resourceExists = context.getResource(requestUri) != null;
        } catch (IOException e) {
            // 资源不存在时会抛出IO异常,直接标记为不存在
        }
        
        if (!resourceExists) {
            // 根据路径转发到对应区域404
            if (requestUri.startsWith("/a/")) {
                request.getRequestDispatcher("/a/404.html").forward(request, response);
                return;
            } else if (requestUri.startsWith("/b/")) {
                request.getRequestDispatcher("/b/404.html").forward(request, response);
                return;
            }
        }
        
        // 资源存在,继续执行后续请求链
        filterChain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}
}

步骤2:配置Filter映射

在web.xml中注册Filter,并映射到所有请求:

<filter>
    <filter-name>Locale404Filter</filter-name>
    <filter-class>com.yourcompany.web.Locale404Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Locale404Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注意事项

  • 确保/a/404.html、/b/404.html和/default-404.html已经放置在Web应用的对应目录下
  • 对于方案一,主流容器(Tomcat、Jetty、WildFly等)都会自动传递javax.servlet.error.request_uri属性,无需额外配置
  • 如果你的应用使用Java EE 7+,可以用@WebServlet和@WebFilter注解替代web.xml配置,让代码更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:18:11