Prevent Browser From Caching Resources Using Servlet Filter

Introduction

In this tutorial I am going to tell you how you can prevent cache in browser using Servlet in web applications. Sometimes you may need to clear the browser cache or prevent the browser from caching resources so that users always get the latest output from the server. Disabling caching of web pages ensures resources are coming every time from the server instead of the cached version.

In every browser, you’ll find an option to disable caching or even you can clear the cached resources but this type of caching is client side caching and generally it is not good idea to rely on whether users will disable cache or clear cache in the browsers. Therefore you may want to ensure that every time a page is requested will bring the updated content from the server.

I assume that you have Java, JSP and Servlet based application where you want to get updated or recent content on your web pages.

Here is an example on how to prevent browser from caching resources.

Prerequisites

Java, JSP, Servlet

Build File

The following pom.xml file can be used for the maven based application:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>servlet-nocache-filter</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>11</maven.compiler.source>
		<maven.compiler.target>11</maven.compiler.target>
	</properties>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>4.0.1</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>

	<build>
		<finalName>servlet-nocache-filter</finalName>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.8.1</version>
			</plugin>
			<plugin>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.2.2</version>
			</plugin>
		</plugins>
	</build>
</project>

HTTP Header Constants

You need to define some constants which are mainly found in HTTP headers of the request.

public enum HTTPCacheHeader {
    CACHE_CONTROL("Cache-Control"),
    EXPIRES("Expires"),
    PRAGMA("Pragma"),
    private String name;
    private HTTPCacheHeader(String name) {
        this.name = name;
    }
    public String getName() {
        return this.name;
    }
}

The above enum constants are used for http headers. For more information on enum please read how to create enum in Java.

Servlet Filter

You need to create a Servlet filter that will actually prevent browser caching for each request coming from the client.

This servlet filter actually sets some cache control headers so that browser will not cache resources.

package com.roytuts.servlet.nocache.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class NoCacheFilter implements Filter {

	public NoCacheFilter() {
	}

	@Override
	public void destroy() {
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		
		HttpServletResponse httpServletResp = (HttpServletResponse) response;
		// set cache directives
		httpServletResp.setHeader(HTTPCacheHeader.CACHE_CONTROL.getName(), "no-cache, no-store, must-revalidate"); // HTTP
																													// 1.1
		httpServletResp.setHeader(HTTPCacheHeader.PRAGMA.getName(), "no-cache"); // HTTP 1.0
		httpServletResp.setDateHeader(HTTPCacheHeader.EXPIRES.getName(), 0L); // Proxies

		// pass the request along the filter chain
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig fConfig) throws ServletException {
	}

}

So the above filter adds http header directives for each web page and prevents caching. You are not actually clearing the cache rather preventing browser from caching resources.

Deployment Descriptor – web.xml

Now in order to let web application work with the servlet you need to make corresponding entry of servlet filter into deployment descriptor – web.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<!-- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
	id="WebApp_ID" version="3.0"> -->

<web-app version="4.0"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
   http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">

	<display-name>No Cache Filter in Web App</display-name>

	<filter>
		<display-name>NoCacheFilter</display-name>
		<filter-name>NoCacheFilter</filter-name>
		<filter-class>com.roytuts.servlet.nocache.filter.NoCacheFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>NoCacheFilter</filter-name>
		<url-pattern>*.jsp</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
	</filter-mapping>

	<session-config>
		<session-timeout>20</session-timeout>
	</session-config>

	<welcome-file-list>
		<welcome-file>/index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

I have put entry of the servlet filter into web.xml file for each requested or forwarded jsp page.

Source Code

Download

Leave a Reply

Your email address will not be published. Required fields are marked *