spring SpringMVC 可以配置为处理所有请求,但排除静态内容目录吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1234298/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can SpringMVC be configured to process all requests, but exclude static content directories?
提问by Rich Kroll
If I map my spring application to process all incoming requests ('/*'), then requests for static content return 404's. For example, a request for "myhost.com/css/global.css" would return a 404, even though the resource exists as Spring intercepts the request.
如果我映射我的 spring 应用程序来处理所有传入的请求 ('/*'),那么对静态内容的请求将返回 404。例如,对“myhost.com/css/global.css”的请求将返回 404,即使资源存在,因为 Spring 拦截了该请求。
The alternative is to map SpringMVC to a subdirectory (for example '/home/'), but in this case, you must pass this directory in all links within the application. Is there a way to map SpringMVC to '/' and exclude a set of directories from processing?
另一种方法是将 SpringMVC 映射到一个子目录(例如“/home/ ”),但在这种情况下,您必须在应用程序内的所有链接中传递此目录。有没有办法将 SpringMVC 映射到“/”并从处理中排除一组目录?
My current web.xml configuration is:
我当前的 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 I would like to have the mapping be something like the following:
理想情况下,我希望映射如下所示:
<servlet-mapping>
<servlet-name>springApp</servlet-name>
<url-pattern>/*</url-pattern>
<exclude>/css/*,/js/*</exclude>
</servlet-mapping>
Is this type of thing possible?
这种事情可能吗?
采纳答案by ChssPly76
If you want to do this with Spring only, it's possible but a bit messy:
如果你只想用 Spring 来做到这一点,这是可能的,但有点乱:
- You'll either need to use a SimpleUrlHandlerMappingfor which you can explicitly specify URL patterns which should be mapped to controllers OR extend it to support "ignore" URLs like "css/**".
- You'll need to write your own HttpRequestHandlerimplementation that would basically consist of "getServletContext().getRequestDsipatcher().include()" call to return the requested resource as is.
- You'll have to register that handler as defaultHandler for the above SimpleUrlHandlerMapping.
- 您要么需要使用SimpleUrlHandlerMapping,您可以明确指定应映射到控制器的 URL 模式或扩展它以支持“忽略”URL,如“css/**”。
- 您需要编写自己的HttpRequestHandler实现,该实现基本上由“getServletContext().getRequestDsipatcher().include()”调用组成,以按原样返回请求的资源。
- 您必须将该处理程序注册为上述 SimpleUrlHandlerMapping 的 defaultHandler。
Once all that is done, all requests that can't be mapped to your controllers will be forwarded to your HttpRequestHandlerand served "as is".
完成所有这些后,所有无法映射到您的控制器的请求都将转发给您HttpRequestHandler并“按原样”提供服务。
回答by atrain
NOTE: this answer applies to Spring 3.0.4+ ONLY
注意:此答案仅适用于 Spring 3.0.4+
(BTW, this question has also been dealt with here: Spring serving static content with mvc:resources, invalid xsd)
(顺便说一句,这个问题也在这里处理:Spring services static content with mvc:resources, invalid xsd)
Check out the Spring mvc-showcase project in the Spring subversion samples repository. It shows exactly what you want to do, namely that you can delineate static resources which will not be processed by the DisapatcherServlet. See file /mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml. Here's a snippet of how I handle these exclusions, where the JS, CSS, and images are in the app context root (with the MVC namespace mapped to mvc:
查看 Spring Subversion 示例存储库中的 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/" />
回答by atrain
I solved by serving static content through the 'default' servlet, that just serve the content to the client. So my web.xml looks like this:
我通过通过“默认”servlet 提供静态内容来解决,该 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 -->
Hope this helps.
希望这可以帮助。
回答by Daniel Egan
Simplest way for me (if using a late enough version of Spring) is
对我来说最简单的方法(如果使用足够晚的 Spring 版本)是
<mvc:resources mapping="/**/*.js" location="/"/>
<mvc:resources mapping="/**/*.css" location="/"/>
...
回答by Alex Beardsley
One way to do it would be with Filters. You'd have to write a little bit of custom code but it's not bad. Here's an example if you don't want to pass *.css or *.js files to your Spring servlet:
一种方法是使用过滤器。您必须编写一些自定义代码,但这还不错。如果您不想将 *.css 或 *.js 文件传递给 Spring servlet,请使用以下示例:
web.xml:
网页.xml:
<filter-mapping>
<filter-name>fileTypeFilter</filter-name>
<filter-class>foo.FileTypeFilter</filter-class>
<url-pattern>/*</url-pattern>
</filter-mapping>
Java class:
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;
}
}
I haven't tested this, but I think it will work.
我没有测试过这个,但我认为它会起作用。
EDIT: There's isn't any exclude functionality in the servlet spec. I don't think there is a good way to do this within Spring, but it essentially achieves the same thing in your post.
编辑:servlet 规范中没有任何排除功能。我认为在 Spring 中没有什么好的方法可以做到这一点,但它在您的帖子中基本上实现了相同的目标。
EDIT 2: If you want to be able to easily change what gets filtered, you could just use Spring to inject something into the Filter at runtime.
编辑 2:如果您希望能够轻松更改过滤的内容,您可以在运行时使用 Spring 将某些内容注入过滤器。
EDIT 3: I just realized if you forward directly to the file, it'll do the filter again and you'll get caught in an infinite loop. There might be another way to do this with filters, but I'm honestly not sure what it is.
编辑 3:我刚刚意识到如果你直接转发到文件,它会再次进行过滤,你会陷入无限循环。使用过滤器可能还有另一种方法可以做到这一点,但老实说,我不确定它是什么。
回答by Darren Greaves
What are you using to serve your static images? If it's Apache then you could configure Apache to not pass css/js requests to your app server.
您使用什么来提供静态图像?如果是 Apache,那么您可以将 Apache 配置为不将 css/js 请求传递到您的应用服务器。
If you are using Tomcat you'd put something like this in your httpd.conf:
如果您使用的是 Tomcat,您可以在 httpd.conf 中添加如下内容:
JkUnMount /*.css webapp
Where 'webapp' is the entry from your workers.properties.
其中“webapp”是您的workers.properties 中的条目。
Sorry I can't give you a pure Spring solution, but this is how I do it.
对不起,我不能给你一个纯粹的 Spring 解决方案,但我就是这样做的。
回答by Green Lei
I got the same problem and here is how I solved it:
我遇到了同样的问题,这是我解决的方法:
The following was added to the web.xml file:
以下内容已添加到 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>
The following was added to the spring3 MVC servlet bean definition file (such as applicationContext.xml, the file that is configured in web.xml as the contextConfigLocation.):
spring3 MVC servlet bean定义文件(如applicationContext.xml,web.xml中配置为contextConfigLocation的文件)添加如下内容:
<mvc:annotation-driven />
<mvc:default-servlet-handler />
回答by user3193801
In my case everything was ok. But i have a problem in a Controller
就我而言,一切正常。但是我在控制器中遇到了问题
that was my problem @RequestMapping( method = RequestMethod.GET)
那是我的问题@RequestMapping(method = RequestMethod.GET)
y change for this:
y 为此更改:
@RequestMapping(value = "/usuario", method = RequestMethod.GET)
and it works
它有效
look for a controller that has bad @RequestMappgin and change.
查找@RequestMappgin 错误的控制器并进行更改。
回答by webpro2828
I use virtual URL path to retrieve the resource I need. Typically I use Spring MVC, so I couldn't have javascripts and css under /WEB-INF/views folder. I came up with this custom servlet to ONLY allow access to .js & .css files within /WEB-INF/views folder. In your case, if you move the /css folder and /js folder to a parent folder such as /resource then my solution will be applicable to you.
我使用虚拟 URL 路径来检索我需要的资源。通常我使用 Spring MVC,所以我不能在 /WEB-INF/views 文件夹下有 javascripts 和 css。我想出了这个自定义 servlet,只允许访问 /WEB-INF/views 文件夹中的 .js 和 .css 文件。在您的情况下,如果您将 /css 文件夹和 /js 文件夹移动到 /resource 等父文件夹,那么我的解决方案将适用于您。
You can change the String url = "YOUR_RESOURCE_FOLDER"
您可以更改字符串 url = "YOUR_RESOURCE_FOLDER"
So for example, virtual path can be something like http://www.mysite.com/resources/path/path/app.js
例如,虚拟路径可以类似于http://www.mysite.com/resources/path/path/app.js
That will map to my /WEB-INF/views/path/path/app.js
这将映射到我的 /WEB-INF/views/path/path/app.js
web.xml
网页.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);
}
}
}
}
回答by Vikram
If you are using Spring 3.0.4 and above you should use solution provided by atrain
如果您使用的是 Spring 3.0.4 及更高版本,则应使用atrain 提供的解决方案
Otherwise, you can do this simplething:
否则,你可以做这个简单的事情:
perhaps you have following static directory structure you want to serve:
也许您有以下要服务的静态目录结构:
WebContent
|
WEB-INF
|
public
|
css
|
js
|
img
EclipseDynamic web projects by default generate following structure: WebContent/WEB-INF. Move the publicfolder out of your WEB-INF directory into WebContentdirectory.
Eclipse默认情况下,动态 Web 项目生成以下结构:WebContent/WEB-INF. 将public文件夹从 WEB-INF 目录移到WebContent目录中。
On client side
在客户端
refer your static files in following way:
通过以下方式引用您的静态文件:
<link rel="stylesheet" type="text/css" href="public/css/mystyles.css">
Here is my reference.
这是我的参考。

