我正在使用带有默认注释映射的 Spring 3.2.2 Web MVC。我使用这样的 servlet 映射:
<servlet>
<servlet-name>profil</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>de.kicktipp.web.config.servlets.ProfilServletConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>profil</servlet-name>
<url-pattern>/info/profil/*</url-pattern>
</servlet-mapping>
这是我们的 servlet 配置:
@Configuration
@ComponentScan("de.kicktipp.controller")
@EnableWebMvc
public class ProfilServletConfig extends WebMvcConfigurerAdapter
{
@Override
public void addInterceptors ( InterceptorRegistry registry )
{
// we add a few interceptors here
}
@Bean
public DefaultRequestToViewNameTranslator viewNameTranslator ( )
{
DefaultRequestToViewNameTranslator defaultRequestToViewNameTranslator = new DefaultRequestToViewNameTranslator();
defaultRequestToViewNameTranslator.setStripExtension(false);
defaultRequestToViewNameTranslator.setAlwaysUseFullPath(false);
defaultRequestToViewNameTranslator.setPrefix("profil/");
return defaultRequestToViewNameTranslator;
}
}
通配符匹配很重要,因为我们想用这种模式匹配许多 url,比如/info/profil/page1
,/info/profil/page2
等等。
当我想匹配/info/profil
没有尾部斜杠的“基本”URL 时,它会被 servlet“配置文件”拾取。
现在我尝试了三种控制器方法来匹配/info/profil
处理程序方法:
@RequestMapping("/")
protected void get1 () {}
@RequestMapping("")
protected void get2 () {}
@RequestMapping("/info/profil")
protected void get3 () {}
只有最后一个有效。这是因为如果 servlet 中的路径为空字符串,则 UrlPathHelper#getLookupPathForRequest(javax.servlet.http.HttpServletRequest) 返回应用程序中的完整路径:
public String getLookupPathForRequest(HttpServletRequest request) {
// Always use full path within current servlet context?
if (this.alwaysUseFullPath) {
return getPathWithinApplication(request);
}
// Else, use path within current servlet mapping if applicable
String rest = getPathWithinServletMapping(request);
if (!"".equals(rest)) {
return rest;
}
else {
return getPathWithinApplication(request);
}
}
对于对“/info/profil/”的请求,该方法将返回“/”,但对于“/info/profil”(没有尾部斜杠),它将返回“/info/profil”,因为其余变量是空字符串并且在前面该方法返回 pathWithinApplication。
其他路径通常与 servlet 映射中的路径匹配(因为 alwaysUseFullPath 默认为 false)。但是“根”路径与应用程序内部的完整路径匹配(就像它总是在 alwaysUseFullPath 为真时一样)。
为什么会这样?为什么 spring 不尝试匹配空字符串,而是尝试匹配应用程序中的路径?