关于spring:@RequestMapping欢迎文件

@RequestMapping welcome file

我的目标是将 /{any path} 和 *.html 映射到不映射 /* 的 servlet。例如:

1
2
3
4
5
6
7
8
9
map:
/foo
/foobar/
/bar.html
/foo/bar.html

don't map:
/foo.js
/bar.pdf

为了做到这一点,我有一个 servlet 和欢迎文件,映射如下:

web.xml:

1
2
3
4
5
6
7
8
<servlet-mapping>
 <servlet-name>someServlet</servlet-name>
 <url-pattern>*.html</url-pattern>
</servlet-mapping>

<welcome-file-list>
 <welcome-file>index.html</welcome-file>
</welcome-file-list>

在控制器中,我有

1
2
3
4
@RequestMapping(value="/index.html", method=RequestMethod.GET)
public ModelAndView showPage(HttpServletRequest request){
  ...
}

这不起作用 - servlet 不会在 /test 上触发。但是,我发现如果我在 /test/index.html 创建一个空白文件,那么它确实可以工作 - 我假设默认 servlet 通过查找 index.html.

会有所帮助

不幸的是,我不能依赖静态文件。有没有什么办法可以让这个映射工作而不需要空白文件破解并且不映射 /* 到 servlet?


答案取决于你是否希望Spring处理:

  • 只有以 .html 结尾或没有扩展名的 URL,或者
  • 所有 URL,除了以 .js 和 .pdf 等结尾的 URL

这两个规则都将与您在问题中提供的列表相匹配。然而,第二个更容易实现。如果您有一个不希望 Spring 处理的已知扩展列表,只需将 web.xml 文件中的这些文件映射到默认处理程序,如下所示:

1
2
3
4
5
6
7
8
<servlet-mapping>
    <servlet-name>someServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>

但是,这只有在您知道所有不想让 Spring 处理的扩展时才有效,因为您必须在 web.xml 中列出每个扩展。

如果你真的想拒绝 .html 以外的任何扩展名,那么你需要以某种方式覆盖 Spring 的默认行为。我不会在这里讨论,因为我认为上面是一个更好的选择。但是这个问题解释了两种可能的方法:spring mvc how to bypass DispatcherServlet for *.html files?