【问题标题】:In a servlet mapping in Spring MVC how do I map the root of a url pattern directory?在 Spring MVC 的 servlet 映射中,如何映射 url 模式目录的根目录?
【发布时间】:2012-11-04 13:05:35
【问题描述】:
<servlet-mapping>
    <servlet-name>testServlet</servlet-name>
    <url-pattern>/test/*</url-pattern>
</servlet-mapping>

如果我点击 /test/page,以上将起作用。但是,点击 /test/test/ 将不起作用。我用的是Spring MVC,我的请求映射如下:

@RequestMapping(value = {"","/"})

编辑:

我正在使用独立项目进行验证,但这似乎是 Spring 的 UrlPathHelper 的错误。当同时存在上下文和 servlet 路径时,以下方法返回不正确的路径,并且您在没有尾部斜杠的情况下点击了 servlet。

public String getPathWithinApplication(HttpServletRequest request) {
    String contextPath = getContextPath(request);
    String requestUri = getRequestUri(request);
    if (StringUtils.startsWithIgnoreCase(requestUri, contextPath)) {
        // Normal case: URI contains context path.
        String path = requestUri.substring(contextPath.length());
        return (StringUtils.hasText(path) ? path : "/");
    }
    else {
        // Special case: rather unusual.
        return requestUri;
    }
}

例如,假设我有一个“admin”上下文和以下 servlet 映射:

<servlet-mapping>
    <servlet-name>usersServlet</servlet-name>
    <url-pattern>/users/*</url-pattern>
</servlet-mapping>

现在我的一个控制器中有一个请求映射,如下所示:

@RequestMapping(value = {"","/"})

如果我点击 /admin/users 它将不起作用。但是,如果我点击 /admin/users/ 它将起作用。现在,如果我将请求映射更改为以下内容,那么它们都可以工作:

@RequestMapping(value = {"/users","/"})

但是,现在 URL /admin/users/users 也可以使用(这不是我想要的)。

【问题讨论】:

    标签: java spring servlets spring-mvc


    【解决方案1】:

    首先,将 dispatcher servlet 映射到“/”和“/*”之间的区别。 有区别!

    当映射到“/*”时,所有 URL 请求(包括类似“/WEB-INF/jsp/.../index.jsp”的东西)都映射到调度器 servlet。

    其次,当使用 Spring + Tiles 并在您的 tile 定义中返回一些 JSP 时,它被视为内部转发请求,并由与原始请求相同的 servlet 处理。 在我的示例中,我调用根 URL“/”,它被 home() 方法正确捕获,然后由 Tiles 转发到“index.jsp”,再次由 Dispatcher Servlet 处理。 显然,dispatcher servlet 无法处理“index.jsp”,因为它没有控制器。

    是的,它很丑,但看起来它就是这样工作的。

    所以,到目前为止,我找到的唯一解决方案是:将 web.xml 中的“/*”改回“/”。我猜想,Tomcat 的 jsp servlet 会正确呈现 JSP,而不是调度程序 servlet。 不幸的是,这个修复会破坏 Spring 的 ROOT URL 调度,所以你需要暂时放弃使用 ROOT URL + Tiles 的想法。

    请注意,当使用“/*”时,在 web.xml 中添加显式 servlet 映射“.jsp -> Tomcat jsp 没有帮助,而且很糟糕。

    问题还是没有解决。

    这也是 Spring MVC 3.0 中的问题

    【讨论】:

    • 问题不在于使用根路径。如果我使用根路径,那么我总是使用&lt;url-pattern&gt;/&lt;/url-pattern&gt;@RequestMapping(value = {"","/"})。我从来没有遇到过这个问题,我使用的是 Tiles 2 和 Spring MVC 3。问题在于首先指定一个 servlet 路径。每当您指定 servlet 路径信息时,Spring 的请求映射就是之后的一切。所以从技术上讲,相同的请求映射应该可以工作,因为它是 servlet 路径的根。然而,情况似乎并非如此。
    【解决方案2】:

    我的设置通常如下所示:

    <servlet-mapping>
        <servlet-name>testServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    

    控制器,我假设您想平等地处理 /test/test/

    @Controller
    public class MyController {
    
        @RequestMapping("/test")
        public String test() {
            return "redirect:/welcome";
        }
    
        @RequestMapping("/test/")
        public String test() {
            return "redirect:/welcome";
        }
    
        @RequestMapping("/welcome")
        public void test(ModelMap model) {
            // do your stuff
        }
    }
    

    这样的设置会导致DispatcherServlet 处理对*.css*.js 文件的请求,这在大多数情况下是不需要的。我认为这是 Bhavik 描述的问题。对于这些资源,您可以像这样使用 ResourceController:

    <mvc:resources mapping="/css/**" location="/resources/css/" />
    <mvc:resources mapping="/js/**" location="/resources/js/" />
    

    来自/resources/css/resources/js 的文件将被提供,而不会强迫您编写额外的控制器。

    【讨论】:

    【解决方案3】:

    Yevgeniy 是正确的,但是如果您的 DispatcherServlet 正在接管默认 servlet,您必须将其添加到您的 web.xml:

    <welcome-file-list>
        <welcome-file>/</welcome-file>
    </welcome-file-list>
    

    【讨论】:

      【解决方案4】:

      一种不接触 web.xml 文件的方法是将地图设置为默认的欢迎文件路径。

      @RequestMapping("/index.html")
      

      【讨论】:

        【解决方案5】:

        在我的例子中,每个 url 都在工作除了根“/”url
        问题是我没有删除我项目的 webapp 根文件夹中的 index.htm 文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-25
          • 1970-01-01
          • 2011-05-12
          • 2017-03-27
          • 2011-02-24
          • 2014-05-01
          • 2016-01-02
          • 1970-01-01
          相关资源
          最近更新 更多