デフォルトのアノテーション マッピングで Spring 3.2.2 Web MVC を使用しています。次のようなサーブレット マッピングを使用します。
<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>
これがサーブレット構成です。
@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
。
末尾のスラッシュなしで「ベース」URL を一致させたい場合/info/profil
は、サーブレット「プロファイル」によって取得されます。
/info/profil
ここで、ハンドラー メソッドと一致する 3 つのコントローラー メソッドを試しました。
@RequestMapping("/")
protected void get1 () {}
@RequestMapping("")
protected void get2 () {}
@RequestMapping("/info/profil")
protected void get3 () {}
最後の 1 つだけが機能します。これは、サーブレット内のパスが空の文字列の場合、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 を返します。
他のパスは通常、サーブレット マッピング内のパスと照合されます (alwaysUseFullPath のデフォルトは false であるため)。ただし、「ルート」パスは、アプリケーション内のフル パスと照合されます (alwaysUseFullPath が true の場合に常に行われるように)。
なぜこのようになっているのですか?spring が空の文字列と一致させようとせず、代わりにアプリケーション内のパスと一致させようとするのはなぜですか?
ここで春の問題を参照してください https://jira.springsource.org/browse/SPR-10491