Servlets servlet映射url模式中/和/*之间的差异

Servlets servlet映射url模式中/和/*之间的差异,servlets,web.xml,url-pattern,Servlets,Web.xml,Url Pattern,熟悉的代码: 主要的 /* 主要的 / 我的理解是,/*映射到http://host:port/context/* 那/呢?它肯定不会映射到http://host:port/context仅限root用户。事实上,它将接受http://host:port/context/hello,但拒绝http://host:port/context/hello.jsp 有人能解释一下这是怎么回事吗http://host:port/context/hello映射 /* servlet上的/*覆盖所有其他s

熟悉的代码:


主要的
/*
主要的
/
我的理解是,
/*
映射到
http://host:port/context/*

/
呢?它肯定不会映射到
http://host:port/context
仅限root用户。事实上,它将接受
http://host:port/context/hello
,但拒绝
http://host:port/context/hello.jsp

有人能解释一下这是怎么回事吗http://host:port/context/hello映射

/*
servlet上的
/*
覆盖所有其他servlet,包括servlet容器提供的所有servlet,如默认servlet和JSP servlet。无论您发出什么请求,它都将在该servlet中结束。因此,对于servlet来说,这是一个糟糕的URL模式。通常,您只希望在一个服务器上使用
/*
。通过调用,它可以让请求继续发送到任何侦听更特定URL模式的servlet

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

然后还有空字符串URL模式
。当请求上下文根目录时,将调用它。这与请求任何子文件夹时不调用它的方法不同。这很可能是您实际寻找的URL模式,以防您想要一个“”。我只需要承认,我直觉上认为空字符串URL模式
和斜杠URL模式
/
的定义正好相反,所以我可以理解很多初学者对此感到困惑。但事实就是这样

前端控制器
如果你真的想要一个前端控制器servlet,那么你最好把它映射到一个更具体的URL模式上,比如
*.html
*.do
/pages/*
/app/*
,等等。你可以隐藏前端控制器URL模式,并在一个常见的URL模式上覆盖静态资源,比如
/resources/*
/static/*
等,并借助servlet过滤器。另见。应该注意的是,SpringMVC有一个内置的静态资源servlet,所以如果您在Spring中为静态资源配置一个公共URL模式,那么就可以在
/
上映射它的前端控制器。另请参见

我想用映射规则和示例补充BalusC的答案

Servlet 2.5规范中的映射规则:

  • 映射精确的URL
  • 映射通配符路径
  • 地图扩展
  • 映射到默认servlet
  • 在我们的示例中,有三个servlet是我们安装的默认servlet。Tomcat安装了两个servlet来服务jsp和jspx。所以要映射
    http://host:port/context/hello

  • 未安装准确的URL servlet,下一步
  • 未安装通配符路径servlet,下一步
  • 不匹配任何扩展名,下一个
  • 映射到默认servlet,返回
  • 映射
    http://host:port/context/hello.jsp

  • 未安装准确的URL servlet,下一步
  • 未安装通配符路径servlet,下一步
  • 找到扩展servlet,返回

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

    映射主机:port/context/hello.jsp

  • 未安装准确的URL servlet,下一步
  • 找到通配符路径servlet,返回

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

    也许您也需要知道URL是如何映射的,因为我经历了数小时的
    404
    。有两种处理程序处理请求<代码>BeanNameUrlHandlerMapping和
    SimpleUrlHandlerMapping
    。当我们定义一个
    servlet映射时,我们使用的是
    simplerlhandermapping
    。我们需要知道的一件事是,这两个处理程序共享一个名为
    AlwaySuseSellPath
    的公共属性,该属性默认为
    false

    false
    这里表示Spring不会使用完整路径将url映射到控制器。这是什么意思?这意味着定义
    servlet映射时:

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

    这是一场完美的比赛,对吗?但是为什么是404。如前所述,
    alwaysuselfelpath
    的默认值为false,这意味着在您的请求中,只有
    /api/feature/doSomething
    用于查找相应的控制器,但没有控制器关心该路径。您需要将url更改为
    /perfix/perfix/api/feature/doSomething
    或从MyController base
    @RequestingMapping
    中删除
    perfix

    /*
    /
    之间的本质区别是,具有映射
    /*
    的servlet将在任何具有扩展映射的servlet之前被选择(如
    *.html
    ),而具有映射
    /
    的servlet将仅在考虑扩展映射之后被选择(并将用于任何与其他内容不匹配的请求——它是“默认servlet”)

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