2

我的问题很简单。我想让我的静态资源在/static/*上下文中服务,但我的特定 servlet 服务于/*上下文。因为/static/*/*它的一个子集不起作用。我的 web.xml 看起来像这样:

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <display-name>template-guice-jersey-tomcat</display-name>
 <session-config>
     <session-timeout>30</session-timeout>
 </session-config>
 <welcome-file-list>
     <welcome-file>index.jsp</welcome-file>
 </welcome-file-list>

 <!-- set up Google Guice Servlet integration -->
 <filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
 </filter>
 <filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
 </filter-mapping>

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


 <listener>                                                                                                                                      
     <listener-class>de.danbim.templateguicejerseytomcat.GuiceServletConfig</listener-class>                                                     
 </listener>                                                                                                                                     
</web-app>  
4

2 回答 2

5

Here's very clean solution to this problem: http://www.kuligowski.pl/java/rest-style-urls-and-url-mapping-for-static-content-apache-tomcat,5:

Unfortunately after looking into DefaultServlet source I found that DefaultServlet takes only pathInfo part of requested URL, so if your request is /static/styles.css, container translates it into /styles.css. Servlet part is omitted by the DefaultServlet. If you want to access such css file you should use /static/static/styles.css request url.

The simple solution of our problem is to write DefaultFilter class and place it at the beginning of web.xml file. This filter will forward all static content calls to DefaultServlet.

Define a filter which will dispatch the request to the default servlet:

public class DefaultFilter implements Filter {  
  
    private RequestDispatcher defaultRequestDispatcher;  
  
    @Override  
    public void destroy() {}  

    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)   
          throws IOException, ServletException {  
        defaultRequestDispatcher.forward(request, response);  
    }  

    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
        this.defaultRequestDispatcher =   
            filterConfig.getServletContext().getNamedDispatcher("default");  
    }  
}

Add the filter (ahead of the other filters) to web.xml:

<filter>  
    <filter-name>default</filter-name>  
    <servlet-name>default</servlet-name>  
    <filter-class>pl.kuligowski.example.DefaultFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>default</filter-name>  
    <url-pattern>/static/*</url-pattern>  
    <url-pattern>*.ico</url-pattern>  
</filter-mapping>

Only static content calls are matched to DefaultFilter, which simply breaks the filter chain and forwards the request to the DefaultServlet.

于 2013-01-27T08:21:24.587 回答
1

对我来说,这适用于 Tomcat 8.5(我什至没有 web.xml 了):

@WebServlet(urlPatterns = "/*")
public class MainServlet {}

@WebServlet(urlPatterns = { "/static/*", "/gwt/*" })
public class StaticServlet extends org.apache.catalina.servlets.DefaultServlet {}

更具体的 url 模式似乎会自动获得优先权。要扩展 catalina 默认 servlet,请将org.apache.tomcat > tomcat-catalina具有范围的 maven 依赖项添加provided到您的项目中。

您可能(像我一样)会立即遇到这样的问题,即仅对应用程序上下文的请求在解析 html 中的相对路径时存在问题(例如,对于样式表和 javascripts)。

我通过主 servlet 中的重定向解决了这个问题:

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    if(request.getPathInfo() == null) {
      // redirect http://localhost:8080/test -> http://localhost:8080/test/ (add trailing slash)
      // because only then are the relative paths to the gwt scripts correctly resolved
      getResponse().sendRedirect(getRequest().getContextPath() + "/");
      return;
    }

    //...
  }
于 2017-09-08T01:19:51.193 回答