servlet 映射 url 模式中/和/* 之间的区别 [英] Difference between / and /* in servlet mapping url pattern

查看:78
本文介绍了servlet 映射 url 模式中/和/* 之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

熟悉的代码:

<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 是如何映射的?

解决方案

/*

servlet 上的 /* 覆盖所有其他 servlet,包括 servletcontainer 提供的所有 servlet,例如默认 servlet 和 JSP servlet.无论您发出什么请求,它都会在那个 servlet 中结束.因此,这对于 servlet 来说是一个糟糕的 URL 模式.通常,您希望在 /*仅noreferrer">过滤器.通过调用 FilterChain#doFilter().

/

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

然后还有空字符串 URL 模式 .这将在请求上下文根时调用.这不同于 ; 方法是在请求任何子文件夹时不调用它.如果您想要主页 servlet".我只需要承认,我直觉上希望空字符串 URL 模式 和斜杠 URL 模式 / 完全相反,所以我可以理解很多初学者对此感到困惑.但事实就是这样.

前控制器

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

The familiar code:

<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>

My understanding is that /* maps to http://host:port/context/*.

How about /? It sure doesn't map to http://host:port/context root only. In fact, it will accept http://host:port/context/hello, but reject http://host:port/context/hello.jsp.

Can anyone explain how is http://host:port/context/hello mapped?

解决方案

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

The /* on a servlet overrides all other servlets, including all servlets provided by the servletcontainer such as the default servlet and the JSP servlet. Whatever request you fire, it will end up in that servlet. This is thus a bad URL pattern for servlets. Usually, you'd like to use /* on a Filter only. It is able to let the request continue to any of the servlets listening on a more specific URL pattern by calling FilterChain#doFilter().

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

The / doesn't override any other servlet. It only replaces the servletcontainer's builtin default servlet for all requests which doesn't match any other registered servlet. This is normally only invoked on static resources (CSS/JS/image/etc) and directory listings. The servletcontainer's builtin default servlet is also capable of dealing with HTTP cache requests, media (audio/video) streaming and file download resumes. Usually, you don't want to override the default servlet as you would otherwise have to take care of all its tasks, which is not exactly trivial (JSF utility library OmniFaces has an open source example). This is thus also a bad URL pattern for servlets. As to why JSP pages doesn't hit this servlet, it's because the servletcontainer's builtin JSP servlet will be invoked, which is already by default mapped on the more specific URL pattern *.jsp.

<url-pattern></url-pattern>

Then there's also the empty string URL pattern . This will be invoked when the context root is requested. This is different from the <welcome-file> approach that it isn't invoked when any subfolder is requested. This is most likely the URL pattern you're actually looking for in case you want a "home page servlet". I only have to admit that I'd intuitively expect the empty string URL pattern and the slash URL pattern / be defined exactly the other way round, so I can understand that a lot of starters got confused on this. But it is what it is.

Front Controller

In case you actually intend to have a front controller servlet, then you'd best map it on a more specific URL pattern like *.html, *.do, /pages/*, /app/*, etc. You can hide away the front controller URL pattern and cover static resources on a common URL pattern like /resources/*, /static/*, etc with help of a servlet filter. See also How to prevent static resources from being handled by front controller servlet which is mapped on /*. Noted should be that Spring MVC has a builtin static resource servlet, so that's why you could map its front controller on / if you configure a common URL pattern for static resources in Spring. See also How to handle static content in Spring MVC?

这篇关于servlet 映射 url 模式中/和/* 之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆