如果我映射我的spring应用程序来处理所有传入的请求('/ *'),那么对静态内容的请求将返回404。例如,对“myhost.com/css/global.css”的请求将返回404,即使资源存在,因为Spring会拦截请求。
另一种方法是将SpringMVC映射到子目录(例如'/ home / '),但在这种情况下,您必须在应用程序中的所有链接中传递此目录。有没有办法将SpringMVC映射到'/ '并从处理中排除一组目录?
我当前的web.xml配置是:
<servlet>
<servlet-name>springApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springApp</servlet-name>
<url-pattern>/home/*</url-pattern>
</servlet-mapping>
Idealy我希望映射类似于以下内容:
<servlet-mapping>
<servlet-name>springApp</servlet-name>
<url-pattern>/*</url-pattern>
<exclude>/css/*,/js/*</exclude>
</servlet-mapping>
这类事可能吗?
答案 0 :(得分:56)
注意:此答案仅适用于Spring 3.0.4+
(顺便说一下,这个问题也在这里讨论过:Spring serving static content with mvc:resources, invalid xsd)
查看Spring subversion samples repository中的Spring mvc-showcase项目。它准确显示了您要执行的操作,即您可以描述DisapatcherServlet不会处理的静态资源。请参阅文件/mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml
。以下是我如何处理这些排除的片段,其中JS,CSS和图像位于应用程序上下文根目录中(MVC名称空间映射到mvc
:
<!-- resources exclusions from servlet mapping -->
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/js/**" location="/js/" />
答案 1 :(得分:27)
我通过“默认”servlet提供静态内容来解决这个问题,这只是将内容提供给客户端。所以我的web.xml看起来像这样:
<servlet>
<servlet-name>MyApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyApp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!-- The 'dynamic' content -->
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping> <!-- The 'static' content -->
希望这有帮助。
答案 2 :(得分:7)
如果你只想用Spring做这个,那可能会有点麻烦:
完成所有操作后,所有无法映射到您的控制器的请求都会转发到您的HttpRequestHandler
并按“原样”提供。
答案 3 :(得分:4)
对我来说最简单的方法(如果使用足够晚的Spring版本)是
<mvc:resources mapping="/**/*.js" location="/"/>
<mvc:resources mapping="/**/*.css" location="/"/>
...
答案 4 :(得分:3)
一种方法是使用过滤器。你必须写一些自定义代码,但它并不坏。如果您不想将* .css或* .js文件传递给Spring servlet,这是一个示例:
的web.xml:
<filter-mapping>
<filter-name>fileTypeFilter</filter-name>
<filter-class>foo.FileTypeFilter</filter-class>
<url-pattern>/*</url-pattern>
</filter-mapping>
Java类:
public class FileTypeFilter implements Filter {
public void init(FilterConfig conf) {
// init logic here
}
public void destroy() {
// release resources here
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
if(shouldExclude(req)) {
chain.doFilter(req, res);
//some logic so the request doesnt go to the servlet
//maybe you could just forward
//the request directly to the file getting accessed. not sure if that would work
}
//file should be passed to the servlet; you can do some logic here
//if you want
}
private boolean shouldExclude(ServletRequest req) {
if(req instanceof HttpServletRequest) {
HttpServletRequest hreq = (HttpServletRequest) req;
return (hreq.getRequestURI().endsWith(".css") ||
hreq.getRequestURI().endsWith(".js"));
}
return false;
}
}
我没有测试过这个,但我认为它会起作用。
编辑:servlet规范中没有任何排除功能。我不认为在Spring中有一个很好的方法可以做到这一点,但它基本上可以在你的帖子中实现同样的目的。
编辑2 :如果您希望能够轻松更改过滤后的内容,您可以在运行时使用Spring将一些内容注入过滤器。
编辑3 :我刚刚意识到如果你直接转发到文件,它会再次进行过滤,你会陷入无限循环。可能还有另一种方法可以使用过滤器,但我真的不确定它是什么。
答案 5 :(得分:2)
您使用什么来提供静态图像? 如果是Apache,那么您可以将Apache配置为不将css / js请求传递给您的应用服务器。
如果你使用的是Tomcat,你可以在httpd.conf中输入这样的东西:
JkUnMount /*.css webapp
'webapp'是您的workers.properties的条目。
抱歉,我不能给你一个纯粹的Spring解决方案,但这就是我的方法。
答案 6 :(得分:2)
我遇到了同样的问题,这就是我解决的问题:
以下内容已添加到web.xml文件中:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
<url-pattern>*.ico</url-pattern>
<url-pattern>*.png</url-pattern>
<url-pattern>*.jpg</url-pattern>
<url-pattern>*.htc</url-pattern>
<url-pattern>*.gif</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
以下内容被添加到spring3 MVC servlet bean定义文件中(例如applicationContext.xml,在web.xml中配置为contextConfigLocation的文件。):
<mvc:annotation-driven />
<mvc:default-servlet-handler />
答案 7 :(得分:0)
对于您希望由Spring调度程序处理的请求,您是否有一致的扩展(我相信大多数Spring示例都使用* .htm)?在这种情况下,您可以映射到您希望处理的扩展名,这些扩展名将绕过您的css和js文件。
否则我同意Nalandial,过滤方法可能是目前最好的工作方式。
答案 8 :(得分:0)
我使用虚拟URL路径来检索我需要的资源。通常我使用Spring MVC,所以我不能在/ WEB-INF / views文件夹下有javascripts和css。我想出了这个自定义servlet,只允许访问.js&amp; / WEB-INF / views文件夹中的.css文件。在您的情况下,如果您将/ css文件夹和/ js文件夹移动到父文件夹(例如/ resource),那么我的解决方案将适用于您。
您可以更改字符串url =“YOUR_RESOURCE_FOLDER”
例如,虚拟路径可以是http://www.mysite.com/resources/path/path/app.js
那将映射到我的/WEB-INF/views/path/path/app.js
的web.xml
<servlet>
<servlet-name>ResourceDispatcherServlet</servlet-name>
<servlet-class>mywebapp.web.ResourceDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ResourceDispatcherServlet</servlet-name>
<url-pattern>/resource/*</url-pattern>
</servlet-mapping>
的servlet
public class ResourceDispatcherServlet extends HttpServlet {
public void init() throws ServletException {
}
public void doGet(HttpServletRequest req, HttpServletResponse rsp) throws ServletException, IOException {
String servletPath = req.getServletPath(); // /resource
String pathInfo = req.getPathInfo(); // /path/path/app.js
String url = "/WEB-INF/views" + pathInfo;
String lastPath = StringUtil.substringAfterLast(pathInfo, "/");
String extension = StringUtil.substringAfterLast(lastPath, ".");
try {
RequestDispatcher dispatcher = null;
if (!StringUtil.isEmpty(extension) && ("js".equals(extension) || "css".equals(extension))) {
dispatcher = req.getRequestDispatcher(url);
}
if (dispatcher != null) {
dispatcher.include(req, rsp);
}
else {
rsp.sendError(404);
}
}
catch (Exception e) {
if (!rsp.isCommitted()) {
rsp.sendError(500);
}
}
}
}
答案 9 :(得分:0)
如果您使用的是Spring 3.0.4及更高版本,则应使用solution provided by atrain
否则,您可以执行 简单 事情:
也许您有以下要提供的静态目录结构:
WebContent
|
WEB-INF
|
public
|
css
|
js
|
img
Eclipse
默认情况下,动态网络项目会生成以下结构:WebContent/WEB-INF
。将public
文件夹移出WEB-INF目录到WebContent
目录。
在客户端
以下列方式引用您的静态文件:
<link rel="stylesheet" type="text/css" href="public/css/mystyles.css">
这是我的reference.
答案 10 :(得分:-1)
使用UrlRewriteFilter将请求重定向到您的servlet更简洁,这里是urlrewrite.xml
<urlrewrite>
<rule>
<from>^/img/(.*)$</from>
<to>/img/$1</to>
</rule>
<rule>
<from>^/js/(.*)$</from>
<to>/js/$1</to>
</rule>
<rule>
<from>^/css/(.*)$</from>
<to>/css/$1</to>
</rule>
<rule>
<from>^/(.*)$</from>
<to>/app/$1</to>
</rule>
<outbound-rule>
<from>/app/(.*)$</from>
<to>/$1</to>
</outbound-rule>
</urlrewrite>
注意:
<rule>
位于底部是很重要的,所以首先会抓住img,js,css <outbound-rule>
是可选的,只是为了使现有的<c:url value="/app/some" />
呈现/some
而不是/app/some
答案 11 :(得分:-1)
通常,大型网站更喜欢使用其他服务器来处理静态内容。 静态内容的请求转到一个服务器,动态转到另一个服务器(在这种情况下使用spring)。
在许多情况下,Nginx服务器(http://nginx.com/),一个最新且速度非常快的服务器。
但这并非易事。很多配置。
答案 12 :(得分:-1)
在我的情况下一切都很好。但我在控制器中遇到了问题
那是我的问题 @RequestMapping(method = RequestMethod.GET)
为此改变:
@RequestMapping(value = "/usuario", method = RequestMethod.GET)
并且有效
查找具有错误@RequestMappgin并更改的控制器。