Static resource access in Spring MVC Restful construction, mvcrestful

Source: Internet
Author: User

Static resource access in Spring MVC Restful construction, mvcrestful

When building a Restful Spring MVC-style application, because in web. xml:

<span style="font-family:Microsoft YaHei;font-size:18px;"><servlet><servlet-name>story</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>story</servlet-name><url-pattern>/</url-pattern></servlet-mapping></span>

All requests are intercepted, including static resource requests, such as page references to image, css, and js files, however, no Controller is defined to respond to these requests. Therefore, these requests cannot be completed.

Here, we should think of a problem: in Tomcat, only the servlet can process requests, even jsp, will be compiled into servlet. Note that in the servlet container, the servlet must process these resources. However, the names of servlets for processing these static resources are not the same for different servlet containers/application servers:
Tomcat, Jetty, JBoss, and GlassFish: the default Servlet name is "default ";
Google App Engine: the default Servlet name is "_ ah_default ";
Resin: the default Servlet name is "resin-file ";
WebLogic: the default Servlet name is "FileServlet ";
WebSphere: the default Servlet name is "SimpleFileServlet ";


There are several common solutions to solve the above problems:

Solution 1: Activate Tomcat's defaservlet servlet to process static Resources

<span style="font-family:Microsoft YaHei;font-size:18px;"><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></span>

For each type of static resources, you need to configure a servlet-mapping separately. At the same time, you need to write it in front of the DispatcherServlet so that the defaservlet servlet can intercept it first. (Do you need to verify it before DispatcherServlet)
However, there is still a problem, that is, the resource file under classpath cannot be accessed. After reading the DefaultServlet configuration items of tomcat, it seems that no directory can be specified.


Solution 2: Spring 3.0.4 and later versions provide <mvc: resources/>

<! -- Process static resources -->

<Span style = "font-family: Microsoft YaHei; font-size: 18px;"> <! -- The uploaded image is cached for one month. Other js, css, and img resources are cached for one year. --> <mvc: resources mapping = "/res/**" location = "/res/" cache-period = "2592000"/> <mvc: resources mapping = "/css/**" location = "/css/" cache-period = "31536000"/> <mvc: resources mapping = "/js/**" location = "/js/" cache-period = "31536000"/> <mvc: resources mapping = "/img/**" location = "/img/" cache-period = "31536000"/> </span>

Mapping maps to ResourceHttpRequestHandler for processing. location specifies the location of the static resource, which can be in the web application root directory and jar package. In this way, static resources can be compressed into jar packages. Cache-period allows static resources to be used for web cache.

Using the <mvc: resources/> element, the mapping URI is registered to the urlMap of SimpleUrlHandlerMapping. The key is the URI pattern value of mapping, and the value is ResourceHttpRequestHandler, in this way, the access to static resources is converted from HandlerMapping to ResourceHttpRequestHandler for processing and returning. Therefore, the classpath directory and the access to static Resources in the jar package are supported.


Solution 3: Use <mvc: default-servlet-handler/>
<Mvc: default-servlet-handler/> registers the "/**" url to the urlMap of SimpleUrlHandlerMapping, and transfers the access to static resources from HandlerMapping to org. springframework. web. servlet. resource. defaultServletHttpRequestHandler processes and returns the result. DefaultServletHttpRequestHandler is the default Servlet of each Servlet container.

Note the default value of the order of HandlerMapping mentioned above:
DefaultAnnotationHandlerMapping: 0
<Mvc: resources/> the automatically registered SimpleUrlHandlerMapping: 2147483646
<Mvc: default-servlet-handler/> the automatically registered SimpleUrlHandlerMapping: 2147483647

Spring will first execute the order value smaller. When accessing an a.jpg image file, you must first use DefaultAnnotationHandlerMapping to find the processor. We cannot find the processor. We do not have a Controller called a.jpg. Search by order value in ascending order. Because the last SimpleUrlHandlerMapping matches "/**", it will definitely match and then respond to the image.
In Spring MVC, accessing an image requires layer-by-layer matching. Performance is definitely not good. Not only Spring MVC, but even Struts, they survive in servlet containers. As long as the servlet containers process these static resources, they must be read into the JVM memory zone. Therefore, to process static resources, we usually add apache or nginx at the front end.
In addition, the best performance should be to directly use the container's DefaultServlet to allow it to intercept static resource requests first, which avoids subsequent forwarding and other operations and improves performance, however, you cannot access the resource files under classpath. Through the mvc: resources tag, matching rules and resource file paths can be easily configured. It should be said that it is the simplest and quickest way. Of course, this is probably the original intention of the mvc namespace design.


Generally, if we use Spring MVC to develop our applications, we often use <c: url value = ""/> to reference some resources, however, resources referenced in css cannot be requested because they do not have a contextPath, such as body {background-image: url (.. /image/bg.jpg)}, you can combine solution 1 in the web. add in xml:

<span style="font-family:Microsoft YaHei;font-size:18px;"><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.jpg</url-pattern></servlet-mapping></span>

Note: The <c: url> label is used to format a URL address as a string and save it in a variable. It supports automatic URL rewriting. The URL specified by value can be a URL of the current project or a URL of another web project. However, the context attribute is required. You can also add parameters to be passed.

Attribute:
Var: variable name;
Value: the URL to be formatted;
Scope: scope. The default value is page;
Context: other project paths;

<C: url var = "urlStr" value = "/user. jsp "> <c: param name =" id "value =" 111 "/> </c: url> <c: url var =" urlStr "value ="/user. jsp "context ="/project "/> <! -- Other web applications of the same container --> <c: out value = "$ {urlStr}"/> <a href = "$ {urlStr}" "> test </a>

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.