代码之家  ›  专栏  ›  技术社区  ›  Candy Chiu

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

  •  166
  • Candy Chiu  · 技术社区  · 14 年前

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

    有谁能解释一下 地图?

    5 回复  |  直到 10 年前
        1
  •  260
  •   Community CDub    8 年前

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

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

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

    这个 / 不重写任何其他servlet。它只为所有不匹配任何其他注册的servlet的请求替换servletcontainer的内置默认servlet。这通常只在静态资源(CSS/JS/image/etc)和目录列表上调用。servletcontainer的内置默认servlet还能够处理HTTP缓存请求、媒体(音频/视频)流和文件下载恢复。通常,您不想覆盖默认的servlet,因为您必须处理它的所有任务,这并不简单(JSF实用程序库 OmniFaces open source example ). 因此,这也是一个错误的servlet URL模式。至于为什么JSP页面没有命中这个servlet,这是因为servletcontainer的内置jspservlet将被调用,它在默认情况下已经映射到更具体的URL模式 *.jsp .

    <url-pattern></url-pattern>

    还有空字符串URL模式 . 这将在请求上下文根时调用。这和 <welcome-file> 在请求任何子文件夹时不调用它的方法。这很可能是您实际寻找的URL模式,以防您需要一个“ home page servlet 以及斜线URL模式 / 完全相反的定义,所以我可以理解很多初学者对此感到困惑。但事实就是如此。

    以防你 事实上 希望有一个前端控制器servlet,那么最好将其映射到一个更具体的URL模式上,比如 *.html , *.do /pages/* , /app/* ,等等。您可以隐藏前控制器URL模式,并覆盖公共URL模式上的静态资源,如 /resources/* , /static/* ,在servlet过滤器的帮助下。另见 How to prevent static resources from being handled by front controller servlet which is mapped on /* . 需要注意的是,Spring MVC有一个内置的静态资源servlet,因此您可以将其前端控制器映射到 / 如果在Spring中为静态资源配置公共URL模式。另见 How to handle static content in Spring MVC?

        2
  •  44
  •   Tiny user825402    10 年前

    我想用映射规则和一个例子来补充BalusC的答案。

    Servlet2.5规范中的映射规则:

    1. 精确映射URL
    2. 地图扩展
    3. 映射到默认的servlet

    http://host:port/context/hello

    1. 下一步,没有安装准确的URL servlets。
    2. 下一步,没有安装通配符路径servlets。
    3. 映射到默认的servlet,return。

    绘制地图 http://host:port/context/hello.jsp

    1. 下一步,没有安装准确的URL servlets。
    2. 找到扩展servlet,返回。
        3
  •  24
  •   hakunami    9 年前

    也许你也需要知道url是如何映射的,因为我 404 BeanNameUrlHandlerMapping SimpleUrlHandlerMapping . 当我们定义 servlet-mapping 简单的lhandlermapping . 我们需要知道的是,这两个处理程序共享一个名为 alwaysUseFullPath 默认为 false .

    这意味着Spring不会使用完整的路径将url映射到控制器。这是什么意思?意思是当你定义 servlet映射 :

    <servlet-mapping>
        <servlet-name>viewServlet</servlet-name>
        <url-pattern>/perfix/*</url-pattern>
    </servlet-mapping>
    

    * 找到控制器。例如,下面的控制器将面对 404个 使用请求时出错 /perfix/api/feature/doSomething

    @Controller()
    @RequestMapping("/perfix/api/feature")
    public class MyController {
        @RequestMapping(value = "/doSomething", method = RequestMethod.GET) 
        @ResponseBody
        public String doSomething(HttpServletRequest request) {
            ....
        }
    }
    

    404个 . 如前所述,默认值为 是假的,这意味着在你的请求中,只有 /api/feature/doSomething 用于查找相应的控制器,但没有控制器关心该路径。您需要将url更改为 /perfix/perfix/api/feature/doSomething perfix 来自MyController基地 @RequestingMapping .

        4
  •  8
  •   hehe    10 年前

    我认为坎迪的回答基本正确。有一小部分我不这么认为。

    1. 下一步,没有安装准确的URL servlets。
    2. 找到通配符路径servlet ,返回。

    我相信为什么“/*”与host:port/context/hello不匹配,因为它将“/hello”视为路径而不是文件(因为它没有扩展名)。

        5
  •  2
  •   Robert Tupelo-Schneck    7 年前

    两者的本质区别 /* / /* 将在任何具有扩展映射(如 *.html / 只有在考虑了扩展映射之后才会被选中(并且将用于任何与其他内容不匹配的请求——它是“默认的servlet”)。

    /* 映射将始终在 地图绘制。或者阻止任何请求到达容器自己的默认servlet。

    /foo/bar )那些路径映射比 /* /foo/* ). 注意,空字符串映射与上下文根完全匹配( http://host:port/context/ ).

    请参阅JavaServlet规范的第12章,3.1版中的 http://download.oracle.com/otndocs/jcp/servlet-3_1-fr-eval-spec/index.html