29-Dec-10 (Created: 29-Dec-10) | More in '00.05-Articles'

Using Servlet Filters to convert extra path info to url query parameters

What needs to happen


/webapp/display/helllourl?a=b&b=c

should become internally


/webapp/display?url=helllourl&a=b&b=c

And


/webapp/update/uploadthis?a=b&b=c

should become internally


/webapp/update?request_name=uploadthis&a=b&b=c

we use request.getPathInfo method

On a URL like the following


http://www.somehost.com/webapp/display/helllourl?a=b&b=c

Assuming the filter is set to respond to "/display/*" the getPathInfo returns


/hellourl

Start with a set of filters for your URL paths


<filter>
   <filter-name>DisplayParamFilter</filter-name>
   <display-name>DisplayParamFilter</display-name>
   <description>DisplayParamFilter</description>
   <filter-class>com.ai.servlets.paramfilters.DisplayParamFilter</filter-class>
   <init-param>
      <param-name>parm1</param-name>
      <param-value>parm1value</param-value>
      <description>description</description>
   </init-param>
</filter>

<filter>
   <filter-name>UpdateParamFilter</filter-name>
   <display-name>UpdateParamFilter</display-name>
   <description>UpdateParamFilter</description>
   <filter-class>com.ai.servlets.paramfilters.UpdateParamFilter</filter-class>
</filter>

<filter-mapping>
   <filter-name>DisplayParamFilter</filter-name>
   <url-pattern>/display/*</url-pattern>
</filter-mapping>    

<filter-mapping>
   <filter-name>UpdateParamFilter</filter-name>
   <url-pattern>/update/*</url-pattern>
</filter-mapping> 

DisplayParamFilter


package com.ai.servlets.paramfilters;

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.HttpServletRequest;

import com.ai.application.interfaces.RequestExecutionException;
import com.ai.application.utils.AppObjects;

public class DisplayParamFilter implements Filter
{
      public void init(FilterConfig filterConfig) 
      throws ServletException
      {
         //AppObjects.info(this,"DisplayParamFilter initialized");
      }

      public void destroy()
      {   
         //AppObjects.info(this,"DisplayParamFilter destroyed");
      }

      public void doFilter(ServletRequest request
                  , ServletResponse response
                  , FilterChain chain)
      throws IOException, ServletException
      {
         try
         {
            //Get the request
            DisplayParamFilterRequest dpfr 
                  = new DisplayParamFilterRequest((HttpServletRequest)request);
            
            //prime it
            dpfr.tFillParamMap();
            
            //continue the request
            chain.doFilter(dpfr,response);
         }
         catch(RequestExecutionException x)
         {
            AppObjects.log("Error:Exception from DisplayParamFilter",x);
            throw new RuntimeException(x);
         }
      }
}

UpdateParamFilter


public class UpdateParamFilter implements Filter
{
      public void init(FilterConfig filterConfig) 
      throws ServletException
      {
         //AppObjects.info(this,"DisplayParamFilter initialized");
      }

      public void destroy()
      {   
         //AppObjects.info(this,"DisplayParamFilter destroyed");
      }

      public void doFilter(ServletRequest request
                  , ServletResponse response
                  , FilterChain chain)
      throws IOException, ServletException
      {
         try
         {
            //Get the request
            UpdateParamFilterRequest dpfr 
                  = new UpdateParamFilterRequest((HttpServletRequest)request);
            
            //prime it
            dpfr.tFillParamMap();
            
            //continue the request
            chain.doFilter(dpfr,response);
         }
         catch(RequestExecutionException x)
         {
            AppObjects.log("Error:Exception from DisplayParamFilter",x);
            throw new RuntimeException(x);
         }
      }//eof-function
}//eof-class

Base Request


public abstract class AParamFilterRequest extends HttpServletRequestWrapper
{
   
   HttpServletRequest m_request = null;
   Map paramMap = new Hashtable();
   
   public AParamFilterRequest(HttpServletRequest inRequest)
   {
      super(inRequest);
      m_request = inRequest;
   }
   /**
    * template method for fill param map.You must call this method.
    * @param request
    * @throws RequestExecutionException
    */
   public void tFillParamMap()
   throws RequestExecutionException
   {
      //fill the usual params into the param map
      fillParameters(m_request,this.paramMap);
      this.qhFillDerivedParameters(m_request, this.paramMap);
   }
   /**
    * Override this method to specialize parameter overloading
    * @param request
    * @param params
    * @throws RequestExecutionException
    */
   protected abstract void qhFillDerivedParameters(HttpServletRequest request, Map params)
   throws RequestExecutionException;

   /**
    * A method to fill basic parameters from http request
    * @param inRequest
    * @param parms
    */
      public void fillParameters(HttpServletRequest inRequest, Map parms )
      {
         for (Enumeration e=inRequest.getParameterNames();e.hasMoreElements();)
         {
            String key = (String)e.nextElement();
            String value = inRequest.getParameter(key);
            parms.put(key,value);
         }
         String aspireContext = inRequest.getContextPath();
         if (aspireContext != null)
         {
            AppObjects.trace("ServletUtils","Retrived appcontex:" + aspireContext);
            if (aspireContext.equals(""))
            {
               parms.put("aspirecontext","");
            }
            else if (aspireContext.length() == 1)
            {
               parms.put("aspirecontext","");
            }
            else
            {
               parms.put("aspirecontext",aspireContext.substring(1));
            }
         }
         else
         {
            AppObjects.log("Warn:Unexpected result. context path not in the request");
         }
      }//eof-function
      
      protected String quGetFirstPathElement(HttpServletRequest request)
      {
         //it will have /stuff1/stuff2
         String path = request.getPathInfo();
         if (path == null)
         {
            //there is no additional path information
            return null;
         }
         AppObjects.info(this,"there is additional pathinfo:" + path);
         //get the first argument
         Vector v = Tokenizer.tokenize(path, "/");
         String firstelement = (String)v.get(0);
         return firstelement;
      }
      
      
      /**
       * Overriden method from base servlet
       */
      public String getParameter(String name)
      {
         return (String)(paramMap.get(name));
      }
      public java.util.Enumeration getParameterNames()
      {
         //Enumeration e = this.paramMap.keySet().iterator();
         return Collections.enumeration(this.paramMap.keySet());
      }
      public java.util.Map getParameterMap()
      {
         return this.paramMap;
      }
}//eof-class

UpdateParamFilterRequest


public class UpdateParamFilterRequest extends AParamFilterRequest
{
   
   public UpdateParamFilterRequest(HttpServletRequest inRequest)
   {
      super(inRequest);
   }
   
   /**
    * Override this method to specialize parameter overloading
    */
   protected void qhFillDerivedParameters(HttpServletRequest request, Map params)
   throws RequestExecutionException
   {
      //If extra pathinfo exists
      //record the first segment as request_name
      String requestIfAvailable =
         this.quGetFirstPathElement(request);
      if (requestIfAvailable == null)
      {
         //there is no additional path
         return;
      }
      //there is additional path
      AppObjects.info(this,
            "Dropping request_name into the hash table:" 
            + requestIfAvailable);      
      params.put("request_name",requestIfAvailable);
   }
}//eof-class

DisplayParamFilterRequest


public class DisplayParamFilterRequest extends AParamFilterRequest
{
   
   public DisplayParamFilterRequest(HttpServletRequest inRequest)
   {
      super(inRequest);
   }
   
   /**
    * Override this method to specialize parameter overloading
    */
   protected void qhFillDerivedParameters(HttpServletRequest request, Map params)
   throws RequestExecutionException
   {
      //If extra pathinfo exists
      //record the first segment as request_name
      String urlIfAvailable =
         this.quGetFirstPathElement(request);
      if (urlIfAvailable == null)
      {
         //there is no additional path
         return;
      }
      //there is additional path
      AppObjects.info(this,
            "Dropping url into the hash table:" 
            + urlIfAvailable);      
      params.put("url",urlIfAvailable);
   }
}//eof-class

References

1. Java Server Side api ver 1.6

2. Look up just servlet package classes

3. Java Programming NOtes

4. Rewriting SendRedirect to deal with SSL (or https) offloading using servlet filters You can find the basics of servlet filters here. I used this as a starting point for this exercise.