Exclude URL from EhCache Web Cache

You would think that this would be built-in, to easily exclude a URL. Maybe there is a good reason they left it out. Anyway, I recently needed to cache results from webservice hits, so that we could minimize the load on the database. I liked the idea of caching the response to really minimize the execution of code. EhCache Web Cache seemed perfect, until I had to exclude one specific service from the cache. The specs were already given to the customer and the URL could not change. So, I chose to use filters to prevent caching.

First, I created a filter and overrode the doFilter method as seen below.

public class NoCacheFilter implements javax.servlet.Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        /** do nothing **/
    }

    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {

        if (request instanceof HttpServletRequest
            && response instanceof HttpServletResponse) {

            HttpServletRequest httpRequest = (HttpServletRequest) request;
            String requestUri = httpRequest.getRequestURI();
            if(requestUri.contains("/registration/save")) {
                requestUri = requestUri.replace("/vine/", "/vine-nocache/");
                request.getRequestDispatcher(requestUri)
                       .forward(request, response);
            } else {
                chain.doFilter(request, response);
            }
        }
    }

    @Override
    public void destroy() {
        /** do nothing **/
    }
}

Second, I created another controller for URLs that should not be cached.

@Controller
@RequestMapping("vine-nocache")
public class VineNoCacheController {

    @Autowired
    @Qualifier("vineRegisterWsTemplate")
    private WebServiceTemplate vineRegisterWsTemplate;

    @RequestMapping(value = "/site/{siteId}/agency/{agencyId}/offender/{subjectId}
                             /registration/save",
                    produces = "application/json")
    public void registerVictim(@PathVariable Integer siteId,
                               @PathVariable Integer agencyId,
                               @PathVariable String subjectId,
                               @RequestParam(required = false) Boolean enableTTY,
                               @RequestParam(required = false) String pin,
                               @RequestParam EnumLanguage language,
                               @RequestParam String uniqueDeviceId,
                               HttpServletResponse response) throws IOException {

// code omitted to save space
}

Third, I configured the filter in the web.xml. The filters execute in order. So, by putting the no cache filter first, it will execute that doFilter method and if the URI contains the “registration/save”, then forward the request to vine-nocache. If it does not contain that String, then continue down the filter chain(which the next filter is the web cache filter). By using a forward, the end user never knows that it is a different URL.

    <filter>
        <filter-name>VineNoCacheFilter</filter-name>
        <filter-class>com.appriss.patrol.vine.NoCacheFilter</filter-class>
    </filter>
    <filter>
        <filter-name>WebServiceCachingFilter</filter-name>
        <filter-class>com.appriss.patrol.ehcache.WebServiceCachingFilter</filter-class>
        <init-param>
            <param-name>cacheName</param-name>
            <param-value>WebServiceCachingFilter</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>VineNoCacheFilter</filter-name>
        <url-pattern>/vine/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>WebServiceCachingFilter</filter-name>
        <url-pattern>/vine/*</url-pattern>
    </filter-mapping>

If there is a better way, please share. But, this is the best way I found in a short period of time.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s