用于提供静态内容的Servlet

152

我在两个不同的容器(Tomcat和Jetty)上部署web应用程序,但它们用于提供静态内容的默认servlet处理URL结构的方式不同,而我想使用相同的URL结构 (详情)。

因此,我希望在Web应用程序中包含一个小的servlet来提供自己的静态内容(图像、CSS等)。这个servlet应该具有以下属性:

是否有这样的servlet可用?我找到的最接近的是servlet书中的示例4-10

更新: 我想要使用的URL结构 - 以防你想知道 - 简单地是:

    <servlet-mapping>
            <servlet-name>main</servlet-name>
            <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
            <servlet-name>default</servlet-name>
            <url-pattern>/static/*</url-pattern>
    </servlet-mapping>

除非是针对static路径的请求,否则所有请求都应该传递给主servlet。问题在于Tomcat的默认servlet不考虑ServletPath(因此它会在主文件夹中查找静态文件),而Jetty则考虑ServletPath(因此它将在static文件夹中查找)。


你能详细说明一下你想使用的“URL结构”吗?根据链接的示例4-10自己编写似乎是微不足道的工作。我自己已经做过很多次了... - Stu Thompson
我编辑了我的问题以详细说明URL结构。是的,最终我自己编写了一个servlet。请参见下面的答案。 - Bruno De Fraine
1
为什么不使用Web服务器来处理静态内容? - Stephen
4
@Stephen:因为并不总是在Tomcat/Jetty前有一个Apache服务器。为了避免单独进行配置的麻烦。但你说得没错,我可以考虑这个选项。 - Bruno De Fraine
我就是不明白,为什么你不使用像这样的映射来提供静态内容: default / - Maciek Kreft
14个回答

1

检查Tomcat 8.x:如果根servlet映射到“”,则静态资源可以正常工作。 对于servlet 3.x,可以通过@WebServlet("")实现。


1
为了服务于Spring应用程序的所有请求,以及/favicon.ico和/WEB-INF/jsp/*中Spring的AbstractUrlBasedView将要求的JSP文件,您可以重新映射jsp servlet和默认servlet:
  <servlet>
    <servlet-name>springapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>/WEB-INF/jsp/*</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/favicon.ico</url-pattern>
  </servlet-mapping>

  <servlet-mapping>
    <servlet-name>springapp</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

我们不能依赖于*.jsp URL模式在检查任何扩展映射之前匹配路径模式“/*”的标准映射上的jsp servlet。将jsp servlet映射到更深的文件夹意味着它会首先被匹配。精确匹配'/favicon.ico'发生在路径模式匹配之前。更深的路径匹配或精确匹配都可以,但没有扩展匹配能通过“/*”路径匹配。映射“/''”到默认servlet似乎不起作用。你会认为确切的“/”会击败springapp上的“/*”路径模式。
以上过滤器解决方案对于来自应用程序的转发/包含的JSP请求无效。为了使其工作,我必须直接将过滤器应用于springapp,在这一点上,url-pattern匹配是无用的,因为所有进入应用程序的请求也会进入其过滤器。所以我添加了模式匹配到过滤器,然后学习了关于“jsp”servlet并看到它不像默认servlet那样删除路径前缀。这解决了我的问题,虽然不完全相同但足够常见。

0
使用org.mortbay.jetty.handler.ContextHandler。您不需要像StaticServlet这样的其他组件。
在Jetty主目录下, $ cd contexts $ cp javadoc.xml static.xml $ vi static.xml

...

<Configure class="org.mortbay.jetty.handler.ContextHandler">
<Set name="contextPath">/static</Set>
<Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/static/</Set>
<Set name="handler">
  <New class="org.mortbay.jetty.handler.ResourceHandler">
    <Set name="cacheControl">max-age=3600,public</Set>
  </New>
 </Set>
</Configure>

使用您的URL前缀设置contextPath的值,并将resourceBase的值设置为静态内容的文件路径。

这对我有用。


-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接