Using the classes CacheRequest and CacheResponse

JDK 1.5 provides a framework into which an caching implementation can be plugged. A standard protocol handler can use the ResponseCache class to get documents from the cache. For example, if the flag useCaches is set on a URLConnection (true by default), an attempt is made to fetch the content from the cache, implementation specified by ResponseCache.

Here’s an example with implementations of ResponseCache, CacheResponse and CacheRequest:

Main.java:

import java.net.*;
import java.io.*;
import java.nio.channels.*;
import java.util.*;

public class Main
{
   public static void main(String []args) throws Exception {
      if (args.length != 1) {
         System.err.println("Usage: java Main <URL>");
         System.exit(0);
      }

      ResponseCache.setDefault(new MyResponseCache());

      // download first time
      System.out.println("Downloading " + args[0] + " a first time");
      String doc = download(args[0]);
      
      System.out.println("nnDownloading " + args[0] + " a second time");
      // download second time (automatically from cache!)
      doc = download(args[0]);
   }
   
   public static String download(String urlString) throws Exception {          
      URL url = new URL(urlString);
      URLConnection connection = url.openConnection();
 
      connection.setConnectTimeout(5000);
      connection.connect();

      BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
      String lineSeparator = System.getProperty("line.separator");
      StringBuffer sb = new StringBuffer();
      String line;
      while ((line = br.readLine()) != null) {
         sb.append(line);
         sb.append(lineSeparator);
      }
      
      return sb.toString();
   }
}

class MyResponseCache extends ResponseCache
{
   public CacheResponse get(URI uri, String requestMethod, Map<String,List<String>> requestHeaders) {
      String cacheFilename = createCacheFilename(uri);
      if (!new File(cacheFilename).exists()) {
         System.out.println(""+uri + " does not exist in cache.");
         return null;
      }
      
      System.out.println("Retrieving " + uri + " from cache.");
      return new MyCacheResponse(createCacheFilename(uri));
   }
   
   public CacheRequest put(URI uri, URLConnection conn) {  
      System.out.println("Storing " + uri + " in cache.");    
      return new MyCacheRequest(createCacheFilename(uri));      
   }
   
   private String createCacheFilename(URI uri) {
      String suri = uri.toString();
      
      String notAllowed = "\/:*?"<>|";
      StringBuffer result = new StringBuffer();
      for (int i=0; i<suri.toString().length(); i++) {
         if (notAllowed.indexOf(suri.charAt(i)) == -1) {
            result.append(suri.charAt(i));
         }
      }
      return result.toString();   
   }
}

class MyCacheResponse extends CacheResponse
{
   private String filename;

   public MyCacheResponse(String filename) {
      this.filename = filename;
   }

   public Map<String, List<String>> getHeaders() throws IOException {
      return new HashMap<String, List<String>>();
   }

   public ReadableByteChannel getBody() throws IOException {
      return Channels.newChannel(new BufferedInputStream(new FileInputStream(filename)));
   }
}

class MyCacheRequest extends CacheRequest
{
   private String filename;
     
   public MyCacheRequest(String filename) {
      this.filename = filename;
   }
   
   public WritableByteChannel getBody() throws IOException {
      return Channels.newChannel(new BufferedOutputStream(new FileOutputStream(filename)));
   }
   
   public void abort() {
   }
}