Java Servlet Programing Laungage

Java Servlet Projects

Servlet Project 3

adplus-dvertising
Create an application to accessing DataCompressionFilter in Servlet
Previous Home Next

In this servlet application, DataCompression Filter is used for compressing requested data through servlet filter.Steps involved in create filter class and mapping into web.xml file. check here.

Application directory structure

Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 <filter>
  <filter-name>DataCompressFilter</filter-name>
  <filter-class>r4r.Filter.DataCompressFilter</filter-class>
 </filter>
 <filter-mapping>
  <filter-name>DataCompressFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>
 <servlet>
  <servlet-name>DataCompressTest</servlet-name>
  <servlet-class>r4r.Filter.DataCompressTest</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>DataCompressTest</servlet-name>
  <url-pattern>/DataCompressTest</url-pattern>
 </servlet-mapping>
 <session-config>
  <session-timeout>
30
  </session-timeout>
 </session-config>
</web-app>

Index.jsp

<%-- 
 Document: index.jsp
--%>
<%@page import="java.io.InputStream, java.io.ByteArrayOutputStream"%>
<%@page import="java.net.URL, java.net.HttpURLConnection"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="Content-Type" 
         content="text/html; charset=UTF-8">
  <title>r4r.co.in-Index</title>
 </head>
 <body>
  <h1>Data Compress Filter!</h1>
  <p>Test the Data Compression is supported, by visiting
    <a href="DataCompressTest">DataCompressTest</a> servlet</p>
  <p>
  <form method="POST">
Enter WebPage URL: <input type="text" 
             name="webURL" value="" size="30" /><br/>
<input type="submit" value="Process URL" />
<input type="reset" value="Reset URL" />
  </form>

  <%
String url = request.getParameter("webURL");
if (url != null) {
 URL webURL = new URL("http://" + url);
 HttpURLConnection connection =
	   (HttpURLConnection) webURL.openConnection();
 //set requested property for Communication link
 connection.setRequestProperty
	     ("User-Agent", "INTERNET(MISE)");
 connection.connect(); //opens a communication link
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 InputStream is = webURL.openStream();
 // read data from inputstream and write it to output stream
 while (is.read() > -1) {
  baos.write(is.read());
 }
 request.setAttribute("webURL", webURL);
 request.setAttribute("size1", 
	    new Integer(baos.toByteArray().length));

 HttpURLConnection compressConnection = 
	   (HttpURLConnection) webURL.openConnection();
 compressConnection.setRequestProperty
	  ("Accept-Encoding", "gzip");
 compressConnection.addRequestProperty
	  ("User-Agent", "INTERNET(MISE)");
 compressConnection.connect();
 ByteArrayOutputStream compressBaos = 
	 new ByteArrayOutputStream();
 InputStream compressIs = compressConnection.getInputStream();
 while (compressIs.read() > -1) {
  compressBaos.write(compressIs.read());
 }
 request.setAttribute
	 ("size2", new Integer(compressBaos.toByteArray().length));
} else {
 //user won't allow to leave textfield empty
}
  %>

  <!-- Display Result on same browser -->
  <p><strong>${webURL}</strong></p>
  Uncompress URL Size: <strong> ${size1} </strong> bytes<br/>
  Compress URL Size: <strong> ${size2} </strong> bytes<br/>
  Save Space: <strong> ${size1-size2} 
  </strong> bytes or <strong> ${(1-size2/size1)*100} </strong>%
 </p>
</body>
</html>

Filter Program

/*
 * Save as a DataCompressFilter.java
 */
package r4r.Filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 *
 * @author R4R
 */
public class DataCompressFilter 
	  implements javax.servlet.Filter {

 private static final boolean debug = true;
 private FilterConfig filterConfig = null;
 private int minThreshold = 128;
 protected int compressThreshold = 0;

 // Constructor
 public DataCompressFilter() {
 }

 /**
  * Init method for this filter 
  */
 @Override
 public void init(FilterConfig filterConfig) {
  this.filterConfig = filterConfig;
  if (filterConfig != null) {
if (debug) {
 log("DataCompressFilter:Initializing filter");
}
String string =
	filterConfig.getInitParameter("compressThreshold");
if (string != null) {
 compressThreshold =
	    Integer.parseInt(string); //type casting
 if (compressThreshold != 
	 0 && compressThreshold < minThreshold) {
  log("compressThreshold either 0 or set to" 
	  + minThreshold + ", means no data compression");
 }
 compressThreshold = minThreshold; //store value
} else {
 compressThreshold = 0;
}
  }
 }

 /**
  *
  * @param request The servlet request we are processing
  * @param response The servlet response we are creating
  * @param chain The filter chain we are processing
  */
 @Override
 public void doFilter(ServletRequest request,
	  ServletResponse response, FilterChain chain)
throws IOException, ServletException {
  if (debug) {
log("DataCompressFilter:doFilter()");
  }
  boolean isCompressedSupport = false;

  if (request instanceof HttpServletRequest) {
//is data compression support
java.util.Enumeration<String> e = 
	((HttpServletRequest) request).getHeaders("Accept-Encoding");
while (e.hasMoreElements()) {
 String string = e.nextElement();
 if (string.indexOf("gzip") != -1) {
  isCompressedSupport = true;
  log("Support Gzip, data compress possible");
 } else {
  isCompressedSupport = false;
  log("Not support Gzip, data compress not possible");
 }
}
  }
  if (!isCompressedSupport) {
//send request|response to next phase in chain
chain.doFilter(request, response);
  } else if (response instanceof HttpServletResponse) {
//initialize ResponseWrapper class 
ResponseWrapper wrappedResponse = 
	new ResponseWrapper((HttpServletResponse) response);
wrappedResponse.setCompressThreshold(compressThreshold);
try {
 chain.doFilter(request, wrappedResponse);
} finally {
 wrappedResponse.finishResponse(); //free resource
}
  }
 }

 /**
  * Return the filter configuration object for this filter.
  */
 public FilterConfig getFilterConfig() {
  return (this.filterConfig);
 }

 /**
  * Set the filter configuration object for this filter.
  */
 public void setFilterConfig(FilterConfig filterConfig) {
  this.filterConfig = filterConfig;
 }

 /**
  * Destroy method for this filter 
  */
 @Override
 public void destroy() {
  filterConfig = null;
  compressThreshold = 0;
 }

 /**
  * log method for print msg over server console 
  */
 public void log(String msg) {
  filterConfig.getServletContext().log(msg);
 }
}

ResponseWrapper Program

/*
 * Save as a ResponseWrapper.java
 */
package r4r.Filter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
/**
 * This response wrapper class extends the 
 support class HttpServletResponseWrapper,
 * which implements all the methods in
 the HttpServletResponse interface, as
 * delegations to the wrapped response. 
 */
class ResponseWrapper extends 
	  javax.servlet.http.HttpServletResponseWrapper {

 protected HttpServletResponse origResponse = null;
 protected ServletOutputStream stream = null;
 protected PrintWriter writer = null;
 protected int threshold = 0;
 protected String contentType = null;

 // Constructor
 ResponseWrapper(HttpServletResponse response) {
  super(response);
  this.origResponse = response; //set response 
 }

 void setCompressThreshold(int compressThreshold) {
  this.threshold = compressThreshold;
 }

 void finishResponse() throws IOException {
  // free resource
  if (writer != null) {
writer.close();
  }
  if (stream != null) {
stream.close();
  }
 }

 public ServletOutputStream createOutputStream()
	  throws IOException {
  //initialize ResponseOutputStream class
  ResponseOutputStream outputStream = 
	     new ResponseOutputStream(origResponse);
  outputStream.setBuffer(threshold);
  return outputStream;
 }

 @Override
 public void flushBuffer() throws IOException {
  ((ResponseOutputStream) stream).flush();
 }

 @Override
 public ServletOutputStream getOutputStream() 
	    throws IOException {
  if (writer == null) {
throw new IllegalStateException
	  ("response already call getWriter() method");
  }
  if (stream == null) {
stream = createOutputStream(); //invoke method
  }
  return stream;
 }

 @Override
 public PrintWriter getWriter() throws IOException {
  if (writer != null) {
return writer;
  }
  if (stream != null) {
throw new IllegalStateException
	 ("response already call getOutputStream() method");
  }
  stream = createOutputStream(); //invoke method
  String charEncode = origResponse.getCharacterEncoding();
  if (charEncode != null) {
writer =
	new PrintWriter(new OutputStreamWriter(stream, charEncode));
  } else {
writer = new PrintWriter(stream);
  }
  return writer;
 }

 @Override
 public void setContentType(String type) {
  this.contentType = type;
  origResponse.setContentType(type);
 }
}

ResponseOutputStream Program

/*
 * Save as a ResponseOutputStream.java
 */
package r4r.Filter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPOutputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
/**
 * This ResponseOutputStream class extends the support
 class ServletOutputStream,
 * which implements all the methods in the OutputStream, as
 * delegations to the write response to stream. 
 */
class ResponseOutputStream extends
	javax.servlet.ServletOutputStream {
 protected int compressThreshold = 0;
 protected byte[] buffer = null;
 protected int bufferCount = 0;
 protected OutputStream gzipstream = null;
 protected boolean closed = false;
 protected HttpServletResponse response = null;
 protected ServletOutputStream output = null;

 // Constructor
 ResponseOutputStream(HttpServletResponse origResponse)
	 throws IOException {
  super();
  this.closed = false;
  this.response = origResponse;
  this.output = origResponse.getOutputStream();
 }

 void setBuffer(int threshold) {
  compressThreshold = threshold;
  buffer = new byte[compressThreshold];
 }

 private void writeToGZip(byte[] b, int off, int len)
	 throws IOException {
  if (gzipstream == null) {
// response is done
if (response.isCommitted()) {
 gzipstream = output; //store value
} else {
 // set header property
 response.addHeader("Content-Encoding", "gzip");
 String vary = response.getHeader("Vary");
 if (vary == null) {
  response.setHeader("Vary", "Accept-Encoding");
 } else {
  // add new Vary header in privous header
  response.setHeader("Vary", vary + ",Accept-Encoding");
 }
 gzipstream = new GZIPOutputStream(output);
}
  }
  gzipstream.write(b, off, len);
 }

 public void flushToGZip() throws IOException {
  if (bufferCount > 0) {
gzipstream.write(buffer, 0, bufferCount);
bufferCount = 0;
  }
 }

 @Override
 public void write(int b) throws IOException {
  if (closed) {
throw new IOException("Cannot write to a closed output stream");
  }
  if (bufferCount >= buffer.length) {
flushToGZip();
  }
  buffer[bufferCount++] = (byte) b;
 }

 @Override
 public void write(byte[] b) throws IOException {
  write(b, 0, b.length);
 }

 @Override
 public void write(byte[] b, int off, int len)
	 throws IOException {
  if (closed) {
throw new IOException("Cannot write to a closed output stream");
  }
  //if len==0 write nothing
  if (len == 0) {
return;
  }
  // get buffer space and compare from length
  if (len <= (buffer.length - bufferCount)) {
System.arraycopy(b, off, buffer, bufferCount, len);
bufferCount += len; // append on buffercount
return;
  }
  //write to GZIP stream
  writeToGZip(b, off, len);
 }

 @Override
 public void flush() throws IOException {
  if (closed) {
throw new IOException("Cannot flush a closed output stream");
  }
  if (gzipstream != null) {
gzipstream.flush();
  }
 }

 @Override
 public void close() throws IOException {
  if (gzipstream != null) {
flushToGZip();// flush all data
gzipstream.close(); // close stream
gzipstream = null;
  } else if (bufferCount > 0) {
output.write(buffer, 0, bufferCount);
        //write data in output stream
bufferCount = 0;
  }
  output.close(); // close output stream
  closed = true;
 }

 public boolean isClosed() {
  return closed;
 }
}

Test program

/*
 * Save as a DataCompressTest.java
 */
package r4r.Filter;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 *
 * @author R4R
 */
public class DataCompressTest extends HttpServlet {

 protected void processRequest(HttpServletRequest request,
  HttpServletResponse response)throws ServletException, IOException 
{
  response.setContentType("text/html;charset=UTF-8");
  PrintWriter out = response.getWriter();

  try {
// get header property
java.util.Enumeration<String> e = request.getHeaders("Accept-Encoding");
while (e.hasMoreElements()) {
 String string = e.nextElement();
 if (string.indexOf("gzip") != -1) {
  out.println("Support Gzip, data compress possible");
 } else {
  out.println("Not support Gzip, data compress not possible");
 }
}
out.println("<br/><a href=\"index.jsp\">Return to Home page</a>");
  } finally {
out.flush(); //free resource
out.close();
  }
 }

 @Override
 protected void doGet(HttpServletRequest request, 
  HttpServletResponse response)throws ServletException,IOException
	 {

  processRequest(request, response);
 }

 @Override
 protected void doPost(HttpServletRequest request,
	 HttpServletResponse response)
throws ServletException, IOException
	 {
  processRequest(request, response);
 }

 @Override
 public String getServletInfo() {
  return "r4r.co.in-DataCompressTest";
 }
}
Output of Program
Previous Home Next