如何防止静态资源被映射在 /* 上的前端控制器 servlet 处理

Posted

技术标签:

【中文标题】如何防止静态资源被映射在 /* 上的前端控制器 servlet 处理【英文标题】:How to prevent static resources from being handled by front controller servlet which is mapped on /* 【发布时间】:2012-11-11 09:32:12 【问题描述】:

我有一个充当前端控制器的 servlet。

@WebServlet("/*")

不过,这也处理 CSS 和图像文件。我怎样才能防止这种情况发生?

【问题讨论】:

【参考方案1】:

你有两个选择:

    使用更具体的 URL 模式,例如 /app/**.do,然后让您的所有页面请求都匹配此 URL 模式。另见Design Patterns web based applications

    同1,但是要从请求URL中隐藏servlet映射;然后,您应该将所有静态资源放在一个公共文件夹中,例如/static/resources,并创建一个过滤器来检查请求 URL 是否不匹配,然后转发到 servlet。这是一个示例,假设您的控制器 servlet 是 @WebServlet("/app/*"),过滤器是 @WebFilter("/*"),并且您的所有静态资源都在 /resources 文件夹中。

    HttpServletRequest req = (HttpServletRequest) request;
    String path = req.getRequestURI().substring(req.getContextPath().length());
    
    if (path.startsWith("/resources/")) 
        chain.doFilter(request, response); // Goes to default servlet.
     else 
        request.getRequestDispatcher("/app" + path).forward(request, response); // Goes to your controller.
    
    

    另见How to access static resources when mapping a global front controller servlet on /*。

【讨论】:

@BalusC 为什么静态资源在通过控制器加载时会抛出 404。我有一个用 /* 映射的过滤器。加载 jquery 文件时,它会抛出错误 404 - 找不到资源。我使用您上面提供的解决方案解决了它。你能解开我的疑惑吗?【参考方案2】:

我知道这是一个老问题,我猜@BalusC 的答案可能很好用。但是我无法修改正在处理的 JSF 应用程序的 URL,所以我只需检查路径并返回是否是静态资源:

    String path = request.getRequestURI().substring(request.getContextPath().length());
    if (path.contains("/resources/")) 
        return;
    

这对我来说很好。

【讨论】:

以上是关于如何防止静态资源被映射在 /* 上的前端控制器 servlet 处理的主要内容,如果未能解决你的问题,请参考以下文章

在 /* 上映射全局前端控制器 servlet 时如何访问静态资源

静态资源被错误地重写到前端控制器 index.php

前端开发如何独立解决跨域问题

springboot静态资源文件的映射

springboot 2.0前端跨域 静态资源本地映射

设置静态资源映射