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

如何让Java Servlet仅映射到无扩展名的请求路径?

实现Java Servlet仅处理无扩展名请求的几种方案

要实现你的需求——让Servlet只在请求路径没有扩展名时执行,带.css、.jsp、.js等扩展名的请求走正常流程,其实有几种实用的方式,我给你拆解一下:

方案一:在Servlet内部直接判断请求路径

这种方式最简单,不需要额外组件,直接在你的Servlet里加判断逻辑:

  1. 把Servlet映射到/*(确保所有请求都会先进入这个Servlet)
  2. 在service方法里检查请求URI是否包含需要排除的扩展名,有就转发给容器的默认处理器,没有就执行自己的业务逻辑

代码示例:

public class MyTargetServlet extends HttpServlet {
    // 定义需要排除的扩展名集合
    private final Set<String> EXCLUDED_EXTS = Set.of("css", "js", "jsp", "html", "png", "jpg");

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        int dotPos = requestURI.lastIndexOf(".");
        
        // 判断是否存在有效扩展名(.不在末尾,且扩展名在排除列表里)
        if (dotPos != -1 && dotPos < requestURI.length() - 1) {
            String ext = requestURI.substring(dotPos + 1).toLowerCase();
            if (EXCLUDED_EXTS.contains(ext)) {
                // 放行给容器处理,比如静态资源交给DefaultServlet,jsp交给JspServlet
                request.getRequestDispatcher(requestURI).forward(request, response);
                return;
            }
        }
        
        // 执行你的核心业务逻辑
        response.getWriter().write("Handling request without extension: " + requestURI);
    }
}

然后在web.xml里配置Servlet映射(或者用Servlet 3.0+的@WebServlet("/*")注解):

<servlet>
    <servlet-name>MyTargetServlet</servlet-name>
    <servlet-class>com.example.MyTargetServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyTargetServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

方案二:用Filter前置拦截(更灵活)

如果你的逻辑需要复用,或者不想在Servlet里掺杂路径判断代码,用Filter是更好的选择——Filter会在所有请求到达Servlet之前拦截,提前过滤掉带指定扩展名的请求:

  1. 编写一个Filter,检查请求URI的扩展名,符合排除条件就直接放行,否则让请求继续到你的Servlet
  2. 把Filter映射到/*,确保所有请求都经过它
  3. 你的Servlet可以正常映射(比如/*或者其他路径)

Filter代码示例:

public class NoExtensionFilter implements Filter {
    private Set<String> excludedExtensions;

    @Override
    public void init(FilterConfig config) throws ServletException {
        // 从配置读取排除的扩展名,方便后期修改
        String extParam = config.getInitParameter("excludedExtensions");
        if (extParam != null && !extParam.isEmpty()) {
            excludedExtensions = Set.of(extParam.split(","));
        } else {
            // 默认排除的扩展名
            excludedExtensions = Set.of("css", "js", "jsp", "html", "png", "jpg");
        }
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();
        int dotPos = requestURI.lastIndexOf(".");
        
        boolean shouldExclude = false;
        if (dotPos != -1 && dotPos < requestURI.length() - 1) {
            String ext = requestURI.substring(dotPos + 1).toLowerCase();
            shouldExclude = excludedExtensions.contains(ext);
        }
        
        if (shouldExclude) {
            // 有需要排除的扩展名,直接放行,让容器处理
            chain.doFilter(req, res);
        } else {
            // 无扩展名,继续到目标Servlet
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
        // 清理资源(如果有的话)
    }
}

web.xml配置Filter和Servlet:

<filter>
    <filter-name>NoExtensionFilter</filter-name>
    <filter-class>com.example.NoExtensionFilter</filter-class>
    <init-param>
        <param-name>excludedExtensions</param-name>
        <param-value>css,js,jsp,html,png,jpg,gif</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>NoExtensionFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>MyTargetServlet</servlet-name>
    <servlet-class>com.example.MyTargetServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>MyTargetServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

如果用Servlet 3.0+注解,Filter可以这样写:

@WebFilter(
    urlPatterns = "/*",
    initParams = @WebInitParam(name = "excludedExtensions", value = "css,js,jsp,html")
)
public class NoExtensionFilter implements Filter {
    // 同上的init、doFilter、destroy方法
}

注意事项

  • 路径判断要考虑特殊情况:比如/test/(末尾带斜杠,无扩展名)应该被处理,/test(无斜杠无扩展名)也应该处理,/test.css?param=1(带参数但有扩展名)要排除
  • 不同容器的默认Servlet名称可能不同,但方案里的转发方式不需要硬编码默认Servlet名称,直接转发原URI即可,容器会自动找到对应的处理器
  • 如果是Spring MVC项目,其实可以通过@RequestMapping的路径规则或者配置ResourceHandler来更优雅地处理,但你问的是普通Servlet,上面的方案更适用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:35:46