【问题标题】:<url-pattern> in <servlet-mapping><servlet-mapping> 中的 <url-pattern>
【发布时间】:2011-09-27 14:27:33
【问题描述】:

案例 1

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

案例 2

  <servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

如果我使用案例 1,那么我的任何页面都不会使用 &lt;link rel="stylesheet" type="text/css" href="${contextPath}/assets/styles.css" /&gt; 进行样式设置,但如果我使用案例 2,则所有页面都会设置样式。

有人能帮我理解为什么吗?

另外,有人可以告诉我应该使用哪种模式,这样我就不必担心扩展了?就像我应该使用/* 一样吗?问题是,如果我现在使用/*,当我在开发我的应用程序时一直在使用*.do,一切似乎都被打破了,不仅是样式,而且我没有得到任何渲染的图片,没有 JCaptcha 等等与链接有关。

如果我尝试从像 http://localhost:8080/myapp/user/1 这样的 REST 客户端发送 GET 请求,它不起作用,我需要在末尾添加 .do 并发送相同的请求,如 http://localhost:8080/myapp/user/1.do

谢谢。

【问题讨论】:

    标签: rest servlets url-pattern


    【解决方案1】:

    浏览器对链接资源(例如 CSS 文件、JS 文件和图像)发送单独的 HTTP 请求。这些请求的 URL 也与 / 的 URL 模式匹配。所以你的myapp servlet 也会被这些请求调用。但是,您的 myapp servlet 似乎无法正确处理它们,因此这些请求返回的内容完全不同。尝试自己单独请求这些资源,以了解您的 servlet 实际返回到网络浏览器的内容:

    http://localhost:8080/myapp/assets/styles.css

    在您的情况下,您想让myapp servlet 忽略对这些资源的请求。最好的方法是创建一个过滤器来做到这一点。假设所有这些资源都在一个名为/assets 的文件夹中,那么您可以通过将您的servlet 映射到更具体的URL 模式来实现这一点,例如/myapp/* 并创建一个Filter 监听/*对于/assets 上的任何请求,透明地继续请求/响应链,并将所有其他请求分派到/myapp

    所以,这个配置

    <filter>
        <filter-name>filter</filter-name>
        <filter-class>com.example.Filter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>controller</servlet-name>
        <servlet-class>com.example.Controller</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>controller</servlet-name>
        <url-pattern>/myapp/*</url-pattern>
    </servlet-mapping>
    

    结合过滤器的doFilter()中的以下内容:

    String uri = ((HttpServletRequest) request).getRequestURI();
    if (uri.startsWith("/assets")) {
        chain.doFilter(request, response); // Goes to container's default servlet.
    } else {
        request.getRequestDispatcher("/myapp" + uri).forward(request, response);
    }
    

    应该适合你。

    【讨论】:

    • http://localhost:8080/myapp/assets/styles.css 给了我styles.css 文件如果我将&lt;url-pattern&gt;*.do 更改为/something/* 但如果我将其更改为/* 它会给我一个404错误。当我在上下文路径之后添加 /something 时,所有链接似乎都在工作。将尝试使用 Spring 3 实现您在上面回答的相同内容,因为我一直在应用程序中使用 Spring 3 控制器。还有一件事,你能帮我理解为什么我在尝试http://localhost:8080/myapp/assets/styles.css/* 而不是/something/* 时得到一个404 错误吗?
    • 因为/* 也匹配styles.css 上的请求。但是,控制器 servlet 显然不明白如何处理它,所以它返回 404。
    【解决方案2】:

    这里是 Oracle J2EE 教程中的相关页面:http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/components.html#148787

    此页面提供了一些示例,并为读者提供了 Servlet 规范:

    有关 servlet 映射的更多信息,例如一般 servlet 映射规则和约定,请参阅 Servlet 2.3 规范的第 11 节:http://www.jcp.org/aboutJava/communityprocess/final/jsr053/

    该规范值得一读,但您需要单击“我同意”才能下载 PDF,因此我无法直接链接到它。


    规范所说的摘要是使用以下规则(按顺序):

    1. 尝试执行完全匹配。
    2. 尝试进行前缀匹配,优先考虑具有最长前缀的匹配。
    3. 尝试进行后缀匹配。
    4. “[T]容器将 尝试提供适合所请求资源的内容。如果“默认” servlet 是为应用程序定义的,它将被使用。”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-24
      • 2012-04-10
      • 1970-01-01
      • 2014-05-24
      • 2012-01-16
      • 2012-03-21
      • 2016-11-07
      • 2018-02-10
      相关资源
      最近更新 更多