Java 在上映射全局前端控制器servlet时如何访问静态资源/*

Java 在上映射全局前端控制器servlet时如何访问静态资源/*,java,servlets,resources,Java,Servlets,Resources,我已经将Spring MVC dispatcher映射为/*上的全局前端控制器servlet 家 org.springframework.web.servlet.DispatcherServlet 家 /* 但是,此映射会停止对静态文件(如CSS、JS、图像等)的访问,这些文件都位于/res/文件夹中 如何访问它们?我建议尽可能使用过滤器而不是默认的servlet 其他两种可能性: 自己编写一个FileServlet。你会发现很多例子,它应该通过URL打开文件并将其内容写入输出流。

我已经将Spring MVC dispatcher映射为
/*
上的全局前端控制器servlet


家
org.springframework.web.servlet.DispatcherServlet
家
/*     
但是,此映射会停止对静态文件(如CSS、JS、图像等)的访问,这些文件都位于
/res/
文件夹中


如何访问它们?

我建议尽可能使用过滤器而不是默认的servlet

其他两种可能性:

自己编写一个FileServlet。你会发现很多例子,它应该通过URL打开文件并将其内容写入输出流。然后,使用它来服务静态文件请求

实例化Google App Engine使用的FileServlet类,并在需要以给定URL提供静态文件时调用该FileServlet上的服务(请求、响应)

您可以将/res/*映射到您的FileServlet或任何东西,以将其从DispatcherServlet的处理中排除,或者直接从DispatcherServlet调用它


我不得不问,Spring文档对这次碰撞有何评论?我从未使用过它。

我也遇到过这个问题,但从未找到一个很好的解决方案。我最终将servlet映射到URL层次结构中更高的一级:


家
/app/*

现在,基本上下文(以及/res目录)中的所有内容都可以由容器提供。

如果使用Tomcat,可以将资源映射到默认servlet:

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

违约
/静止的/*
并使用url http://{context path}/static/res/…访问您的资源


也适用于Jetty,但不确定其他servlet容器。

应用程序引擎中的“静态”文件不能直接被应用程序访问。您需要上传两次,或者自己提供静态文件,而不是使用静态处理程序。

冲突的原因似乎是,默认情况下,上下文根“/”将由org.apache.catalina.servlets.DefaultServlet处理。这个servlet用于处理对静态资源的请求

如果为了处理动态请求而决定使用自己的servlet将其替换掉,那么顶级servlet还必须执行catalina最初的“DefaultServlet”处理程序完成的任何任务

如果您通读tomcat文档,就会发现True Apache(httpd)在处理静态内容方面优于ApacheTomcat,因为它是专门为此而构建的。我猜是因为Tomcat默认使用org.apache.catalina.servlets.DefaultServlet来处理静态请求。由于它都封装在一个JVM中,并且Tomcat打算作为一个Servlet/JSP容器,所以他们可能没有将该类编写为一个超级优化的静态内容处理程序。就在那里。它完成了任务。很好

但这是处理静态内容的东西,它位于“/”。所以,如果你把其他东西放在那里,而那东西不处理静态请求,哎呀,那你的静态资源就没有了

我一直在到处寻找同一个答案,我得到的答案是“如果你不想让它那样做,就不要那样做”


长话短说,您的配置正在用根本不是静态资源处理程序的东西取代默认的静态资源处理程序。您需要尝试不同的配置以获得所需的结果(我也一样)。

您要做的是在web.xml中添加一个欢迎文件

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

index.html
然后将其添加到servlet映射中,这样当有人访问应用程序的根时,他们会在内部被发送到index.html,然后映射会在内部将他们发送到您映射到的servlet

<servlet-mapping>
    <servlet-name>MainActions</servlet-name>
    <url-pattern>/main</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>MainActions</servlet-name>
    <url-pattern>/index.html</url-pattern>
</servlet-mapping>

主要行动
/主要
主要行动
/index.html
最终结果:您访问了/Application,但在不中断任何其他根请求的情况下,您将看到/Application/MainActions servlet


明白了吗?因此,你的应用程序仍然位于子url,但当用户转到你网站的根目录时,它会自动显示。这允许您将/images/bob.img仍放在常规位置,但“/”是您的应用程序。

将您不希望触发servlet处理的文件夹添加到appengine-web.xml文件的
部分

我刚这么做了,看起来一切都开始正常了。这是我的结构:

/

/页数/

/css


我在
部分添加了“/pages/**”和“/css/**”,现在我可以从servlet doGet内部转发到.jsp文件,而不会引起无限循环。

将控制器servlet映射到更具体的
url模式上,如
/pages/*
,将静态内容放在一个特定的文件夹中,如
/static
,并创建一个
过滤器
侦听
/*
,该过滤器透明地延续任何静态内容的链,并向控制器servlet发送其他内容的请求

简言之:


滤波器
com.example.Filter
滤波器
/*
控制器
com.example.Controller
控制器
/页数/*
在过滤器的
doFilter()
中使用以下内容:

HttpServletRequest req=(HttpServletRequest)请求;
字符串路径=req.getRequestURI().substring(req.getContextPath().length());
if(path.startsWith(“/static”)){
chain.doFilter(请求、响应);//转到默认servlet。
}否则{
getRequestDispatcher(“/pages”+path).forward(请求,响应);
}

不,这不会以浏览器地址栏中的
/pages
结束。它是完全透明的。如有必要,您可以将
“/static”
和/或
“/pages”
设置为筛选器的
init参数。

处理此问题的最佳方法是使用某种URL重写。这样,您就可以拥有干净的
< mvc:annotation-driven  /> 
< mvc:default-servlet-handler />
<mvc:resources mapping="/resources/**" location="/public-resources/"/>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>
<mvc:default-servlet-handler />
<servlet>
  <servlet-name>DefaultServlet</servlet-name>
  <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>DefaultServlet</servlet-name>
  <url-pattern>/css/*</url-pattern>
</servlet-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:default-servlet-handler/>
</beans>
@Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
getServletContext().getNamedDispatcher("/").forward(req,res);