Is it possible to configure SpringMVC to handle all requests but exclude static content directories?

If I listed my spring application for processing all incoming requests ('/ *'), then requests for static content return 404. For example, the query โ€œmyhost.com/css/global.cssโ€ will return 404, although the resource exists as spring intercepts the request .

An alternative is to map SpringMVC to a subdirectory (e.g. '/ home /'), but in this case you must pass this directory to all the links in the application. Is there a way to map SpringMVC to '/' and exclude a set of directories from processing?

My current web.xml configuration is:

<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> 

Idealism I would like the display to be something like this:

  <servlet-mapping> <servlet-name>springApp</servlet-name> <url-pattern>/*</url-pattern> <exclude>/css/*,/js/*</exclude> </servlet-mapping> 

Is it possible?

+55
spring spring-mvc configuration
Aug 05 '09 at 16:24
source share
13 answers

If you only want to do this with Spring, this is possible, but a little messy:

  • You need to either use SimpleUrlHandlerMapping , for which you can explicitly specify the URL patterns that should be displayed on the controllers or extend it to support "ignore" URLs such as "css / **".
  • You will need to write your own implementation of HttpRequestHandler , which will mainly consist of "getServletContext (). GetRequestDsipatcher (). Include ()" to return the requested resource as is.
  • You will need to register this handler as defaultHandler for the above SimpleUrlHandlerMapping.

Once all this is done, all requests that cannot be mapped to your controllers will be redirected to your HttpRequestHandler and will be served as-is.

+7
Aug 05 '09 at 19:40
source share

NOTE. This answer only applies to Spring 3.0.4+ ONLY

(By the way, this question was also discussed here: Spring serving static content using mvc: resources, invalid xsd )

Check out the Spring mvc-showcase project in the Spring subversion fetch repository . It shows what exactly you want to do, namely, that you can outline static resources that will not be processed using the DisapatcherServlet. See File /mvc-showcase/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml . Here is a snippet of how I handle these exceptions, where JS, CSS, and images are at the root of the application context (with the MVC namespace mapped to mvc :

 <!-- resources exclusions from servlet mapping --> <mvc:resources mapping="/css/**" location="/css/" /> <mvc:resources mapping="/images/**" location="/images/" /> <mvc:resources mapping="/js/**" location="/js/" /> 
+56
Dec 29 '10 at 17:26
source share

I decided to use static content through the "default" servlet, which simply serves the content for the client. So my web.xml looks like this:

 <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.

+27
Aug 09 '09 at 21:11
source share

The easiest way for me (when using a fairly late version of Spring) is

 <mvc:resources mapping="/**/*.js" location="/"/> <mvc:resources mapping="/**/*.css" location="/"/> ... 
+4
Nov 14
source share

One way to do this would be with filters. You need to write some custom code, but it is not. Here is an example if you do not want to transfer * .css or * .js files to your Spring servlet:

web.xml:

 <filter-mapping> <filter-name>fileTypeFilter</filter-name> <filter-class>foo.FileTypeFilter</filter-class> <url-pattern>/*</url-pattern> </filter-mapping> 

Java class:

 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 have not tested this, but I think it will work.

EDIT . There are no exclusive functionality in the servlet specification. I don't think there is a good way to do this in Spring, but it essentially accomplishes the same thing in your post.

EDIT 2 . If you want to easily change what is being filtered, you can simply use Spring to enter something into the filter at runtime.

EDIT 3 : I realized that if you go directly to the file, it will make a filter again and you will end up in an endless loop. There may be another way to do this with filters, but I'm honestly not sure what it is.

+3
Aug 05 '09 at 19:11
source share

What do you use to serve your still images? If it is Apache, you can configure Apache to not send css / js requests to your application server.

If you use Tomcat, you would add something like this to your httpd.conf:

 JkUnMount /*.css webapp 

Where "webapp" is the entry from your working .properties.

Sorry, I cannot give you a clean Spring solution, but this is how I do it.

+2
Aug 05 '09 at 16:35
source share

I have the same problem, and here is how I solved it:

The following has been added to the web.xml file:

 <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 file has been added to the spring3 MVC bean servlet description file (for example, applicationContext.xml, a file that is configured in web.xml as contextConfigLocation.):

 <mvc:annotation-driven /> <mvc:default-servlet-handler /> 
+2
Sep 22 '15 at 2:49
source share

Do you have a permanent extension for requests that you want to handle with the Spring dispatcher (I believe most Spring examples use * .htm)? In this case, you can map the extensions you want to handle that will bypass your css and js files.

Otherwise, I agree with Nalandial, the Filter approach probably works best at this point.

0
Aug 05 '09 at 19:25
source share

Typically, large websites prefer to use a different server only for processing static content. Requests for static content are sent to one server, and dynamic requests to another (with this spring).

In many cases, the Nginx server (http://nginx.com/) is a recent and very fast server.

But itโ€™s not so difficult. Lots of configurations.

0
Jul 08 '12 at 15:05
source share

I use a virtual URL to get the resource I need. I usually use Spring MVC, so I did not have javascripts and css under the / WEB -INF / views folder. I came up with this custom servlet to ONLY allow access to .js and .css files in the / WEB -INF / views folder. In your case, if you move the / css and / js folder to the parent folder like / resource, my solution will be applicable to you.

You can change the string url = "YOUR_RESOURCE_FOLDER"

So, for example, the virtual path may be something like http://www.mysite.com/resources/path/path/app.js

This will be displayed in my / 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); } } } } 
0
Jul 03 '13 at 19:52
source share

If you are using Spring 3.0.4 and above, you should use the solution provided by atrain

Otherwise, you can do it simply :

perhaps you have the following static directory structure that you want to serve:

 WebContent | WEB-INF | public | css | js | img 

Eclipse Dynamic web projects by default generate the following structure: WebContent/WEB-INF . Move the public folder from the WEB-INF directory to the WebContent directory.

Client side

refer to your static files as follows:

 <link rel="stylesheet" type="text/css" href="public/css/mystyles.css"> 

Here's the link .

0
Mar 06 '14 at 19:12
source share

Clear to use UrlRewriteFilter to redirect a request to your servlet, here is an example 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> 

NOTES:

  • It is important that the last <rule> at the bottom, so img, js, css will be detected first.
  • <outbound-rule> is optional and is only to make an existing
    <c:url value="/app/some" /> render /some instead of /app/some
-one
Apr 09 '10 at
source share

In my case, everything was in order. But I have a problem in the controller

That was my problem @RequestMapping (method = RequestMethod.GET)

y change for this:

 @RequestMapping(value = "/usuario", method = RequestMethod.GET) 

and he works

find the controller with the bad value @RequestMappgin and change it.

-one
Dec 14 '15 at 20:09
source share



All Articles