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规范中的映射规则:
http://host:port/context/hello
http://host:port/context/hello.jsp
我认为坎蒂的回答基本上是正确的。有一小部分我不这么认为 映射主机:port/context/hello.jsp
我相信为什么“/*”与主机: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) {
....
}
}