首页 > 解决方案 > 从@WebServlet urlPattern Java 中排除 CSS、JS 和 IMG 文件

问题描述

我的 Servlet 按slug显示产品详细信息

@WebServlet("/*")
public class ProductDetails extends HttpServlet {

例如 :

mywebsite.com/product-name

但他们无法加载 css、js 和 img 文件,因为它会检测到 slug 的 pathInfo。

如何排除它们以不加载到 servlet 中?

标签: javaservletsjava-ee-8

解决方案


不幸的是,Servlet 规范没有为 URL 模式映射定义排除规则。此外,匹配的路径优先于匹配的后缀(参见 Servlet 4 规范,第 12.1 和 12.2 段)。此 Servlet 上的映射将匹配应用程序上下文路径中的任何内容,包括静态资源。

你能做什么:

  • 您可以拆分逻辑以处理该 servlet 中的静态资源。我不会这样做,它可能会使代码复杂化并损害关注点的分离。
  • 如果您的静态资源位于特定目录中并且没有 slug 可以匹配它(例如,所有 JS、CSS、HTML、图像文件在 下assets/),您可以在此目录下拥有另一个提供静态内容的 Servlet(例如@WebServlet("/assets/*"))。与请求匹配的最长路径映射优先。您仍然需要编写代码以将文件发送回客户端;这段代码相当简单,您有机会自定义静态文件的标题(例如缓存),并且与之前的解决方案相比,处理静态文件的代码位于它自己的 Servlet 中,因此可以很好地分离关注点。
  • 如果您不想自己为静态文件提供服务(我不会责怪您),您可以将逻辑从您的 Servlet 移到另一个类。然后引入一个 Servlet 过滤器,它将首先检查请求是否是静态资源的 GET,如果是,则简单地调用filterChain.doFilter(request,response)并让应用程序服务器处理静态文件。如果没有,它会调用您的逻辑并发送您的 Servlet 将发送的响应。
  • 最后,如果您通过@WebServlet("/")(不是"/*")将您的 Servlet 设置为默认 Servlet。它将接收其他 Servlet 没有的任何请求。应用程序服务器应该为静态内容安装一个 Servlet,它将为您的应用程序中的任何现有 CSS、JS 等文件提供服务。其他任何内容都将在您的默认 Servlet 中结束。

如果您能找到一种方法将静态内容与动态内容分开,例如 下的所有静态内容assets/,虚拟路径下的所有动态内容,那么将您的 Servlet 的映射更改为并完成content/它会容易得多。/content/*


推荐阅读