Question

Suppose I have bound all urls to Spring dispatcher servlet, and set up some .css and .js directories with <mvc:resources> in mvc Spring namespace.

Can I cache those static Spring resources in memory to avoid hitting disk on user request?

(Note that I am not asking about HTTP caching like Not Modified response and also don't mean Tomcat static files caching or setting up another webserver in front of Java webserwer, just Spring solution)

Was it helpful?

Solution

Well, as you say that you want to cache the entire content of your underlying target resource, you have to cache its byte[] from inputStream.

Since <mvc:resources> is backed by ResourceHttpRequestHandler there is no stops to write your own sub-class and use it directly instead of that custom tag.

And implement your caching logic just within overrided writeContent method:

public class CacheableResourceHttpRequestHandler extends ResourceHttpRequestHandler {

        private Map<URL, byte[]> cache = new HashMap<URL, byte[]>();

        @Override
        protected void writeContent(HttpServletResponse response, Resource resource) throws IOException {
            byte[] content = this.cache.get(resource.getURL());
            if (content == null) {
                content = StreamUtils.copyToByteArray(resource.getInputStream());
                this.cache.put(resource.getURL(), content);
            }
            StreamUtils.copy(content, response.getOutputStream());
        }

    }

And use it from spring config as generic bean:

<bean id="staticResources" class="com.my.proj.web.CacheableResourceHttpRequestHandler">
    <property name="locations" value="/public-resources/"/>
</bean>

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>/resources/**=staticResources</value>
    </property>
</bean>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top