小编典典

servlet 映射 url 模式中 / 和 /* 之间的区别

all

熟悉的代码:

<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>main</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

我的理解是/*映射到http://host:port/context/*.

怎么样/?它肯定不会http://host:port/context只映射到根目录。事实上,它会接受http://host:port/context/hello,但会拒绝http://host:port/context/hello.jsp

谁能解释一下是如何http://host:port/context/hello映射的?


阅读 100

收藏
2022-07-29

共1个答案

小编典典

<url-pattern>/*</url-pattern>

on a servlet 覆盖所有其他 servlet,包括 servletcontainer 提供的/*所有 servlet,例如默认 servlet
和 JSP servlet。无论您发出什么请求,它都会在那个 servlet 中结束。因此,这对于 servlet 来说是一个糟糕的 URL
模式。通常,您只想/*在 a
上使用Filter。它能够让请求继续通过调用FilterChain#doFilter().

<url-pattern>/</url-pattern>

/不会覆盖任何其他 servlet 。它只替换 servletcontainer 的内置默认 servlet,用于所有与任何其他已注册 servlet
不匹配的请求。这通常只在静态资源(CSS/JS/image/etc)和目录列表上调用。servletcontainer 内置的默认 servlet
还能够处理 HTTP 缓存请求、媒体(音频/视频)流和文件下载恢复。通常,您不希望覆盖默认
servlet,否则您将不得不处理它的所有任务,这并非微不足道(JSF
实用程序库OmniFaces有一个开源
示例)。因此,这对于 servlet
来说也是一个糟糕的 URL 模式。至于为什么 JSP 页面没有命中这个 servlet,是因为 servletcontainer 内置的 JSP
servlet 会被调用,默认情况下它已经映射到更具体的 URL 模式上*.jsp

<url-pattern></url-pattern>

然后还有空字符串 URL 模式。这将在请求上下文根时调用。<welcome- file>这与请求任何子文件夹时不调用它的方法不同。如果您想要一个“主页servlet ” ,这很可能是您实际寻找的 URL 模式。我只需要承认,我直观地期望空字符串
URL 模式和斜杠 URL 模式/完全相反地定义,所以我可以理解很多初学者对此感到困惑。但是它就是这样啊。

前控制器

如果您 确实 打算拥有一个前端控制器 servlet,那么您最好将其映射到更具体的 URL 模式上,例如*.html, *.do,
/pages/*,/app/*等。您可以隐藏前端控制器 URL 模式并在通用 URL 模式上覆盖静态资源在 servlet
过滤器的帮助下,如/resources/*,等。/static/*另请参阅如何防止静态资源被映射到 /* 的前端控制器 servlet
处理。应该注意的是 Spring MVC有一个内置的静态资源 servlet,所以/如果你在 Spring 中为静态资源配置一个通用的 URL
模式,你可以映射它的前端控制器。

2022-07-29