1

我对 Spring MVC 的 url-pattern 映射如何工作感到困惑。

当 'getServletMappings' 返回 "/" 时,我可以通过 " http://localhost:8080/hello " 得到正确的响应。

但如果我将其更改为“/app”并将 url 更改为“ http://localhost:8080/app/hello ”则不起作用,它会返回 404 错误。

我是不是误会了什么,我也发现“/app/*”可以工作(我可以理解),但为什么不能“/app”?

请检查我的代码:

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
        // works with http://localhost:8080/hello
        return new String[] {
                "/"
        };
        // NOT working with http://localhost:8080/app/hello
        // return new String[] {
        //      "/app"
        //};
    }
}



@RestController
public class HTTPMethodsController {
   @RequestMapping("/hello")
   public String hello() {
       return "Hello SpringMVC.";
   }
}
4

1 回答 1

1

根据Servlet 规范第 12.2 章,servlet 的映射必须使用以下语法:

  • 以“/”字符开头并以“/*”后缀结尾的字符串用于路径映射。
  • 以“*”开头的字符串。前缀用作扩展映射。
  • 空字符串 ("") 是一种特殊的 URL 模式,它精确映射到应用程序的上下文根,即表单应用程序上下文根的请求,即http://host:port//形式的请求。在这种情况下,路径信息是“/”,servlet 路径和上下文路径是空字符串(“”)。
  • 仅包含“/”字符的字符串表示应用程序的“默认”servlet。在这种情况下,servlet 路径是请求 URI 减去上下文路径,并且路径信息为空。
  • 所有其他字符串仅用于完全匹配。

DispatcherServlet因此,将与 URL映射"/app"会导致 servlet 容器仅在完全匹配时将请求路由到它,这意味着仅当您将 url 更改为“ http://localhost:8080/app ”时。这没有为目标特定 Spring 控制器添加额外路径的空间(更准确地说:hello()如果您映射它,您实际上可以点击您的控制器方法,@RequestMapping("/app")因为DispatcherServlet回退到使用整个 url 进行搜索,但实际上这不是您想要的)。

所以映射“/app/*”是正确的,或者您也可以将它映射为带有“/”的默认servlet,如您所见。

于 2019-10-02T22:34:09.887 回答