views:

817

answers:

3

How to use a filter to change an incoming request url :

From : "http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123"

To : "http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123" ?

Frank


Edit : According to BalusC's steps below, I came up with the following lines :

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;

public class Url_Filter implements Filter
{
  private FilterConfig filterConfig;

  public void init(FilterConfig filterConfig) throws ServletException
  {
    this.filterConfig=filterConfig;
  }

  public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException
  {
    HttpServletRequest httpRequest=(HttpServletRequest)request;
    HttpServletResponse httpResponse=(HttpServletResponse)response;

    String Incoming_Url=httpRequest.getRequestURI();
    if (Incoming_Url.startsWith("/Check_License/Dir_My_App/"))
    {
      String Replace_Part=Incoming_Url.substring(Incoming_Url.indexOf("/Dir_My_App"),Incoming_Url.lastIndexOf("/")+1);  // /Dir_My_App/Dir_ABC/
      String New_Url=Incoming_Url.replace(Replace_Part,"?Contact_Id=");                                                  // http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123

      // Use either ServletRequest#getRequestDispatcher() and then RequestDispatcher#forward() to forward the request/response to the new URL (server-side redirect, not reflected in browser address bar)
      RequestDispatcher request_Dispatcher=request.getRequestDispatcher(New_Url);
      request_Dispatcher.forward(request,response);
/*
      // Or cast the incoming ServletResponse to HttpServletResponse and then HttpServletResponse#sendRedirect() to redirect the response to the new URL (client side redirect, reflected in browser address bar).
      httpResponse.sendRedirect(New_Url);
*/
    }
    chain.doFilter(request,response);
  }

  public void destroy()
  {
  }
}

My web.xml look like this :

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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_2_5.xsd"&gt;
    <filter>
        <filter-name>Url_Filter</filter-name>
        <filter-class>PayPal_Monitor.Url_Filter</filter-class>
    </filter>
    <filter-mapping>
          <filter-name>Url_Filter</filter-name>
          <url-pattern>/*</url-pattern>
    </filter-mapping>

    <servlet>
        <servlet-name>PayPal_Monitor</servlet-name>
        <servlet-class>PayPal_Monitor.PayPal_Monitor_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PayPal_Monitor</servlet-name>
        <url-pattern>/PayPal_Monitor</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>Check_License</servlet-name>
        <servlet-class>PayPal_Monitor.Check_License_Servlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Check_License</servlet-name>
        <url-pattern>/Check_License</url-pattern>
    </servlet-mapping>

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

I tried both server-side and client-side redirect with the expected results. It worked, thanks BalusC !

+5  A: 
  1. Implement javax.servlet.Filter.
  2. In doFilter() method, cast the incoming ServletRequest to HttpServletRequest.
  3. Use HttpServletRequest#getRequestURI() to grab the path.
  4. Use straightforward java.lang.String methods like substring(), split(), concat() and so on to extract the part of interest and compose the new path.
  5. Use either ServletRequest#getRequestDispatcher() and then RequestDispatcher#forward() to forward the request/response to the new URL (server-side redirect, not reflected in browser address bar), or cast the incoming ServletResponse to HttpServletResponse and then HttpServletResponse#sendRedirect() to redirect the response to the new URL (client side redirect, reflected in browser address bar).
  6. Register the filter in web.xml on an url-pattern of /* or /Check_License/*, depending on the context path.

Don't forget to add a check in the code if the URL needs to be changed and if not, then just call FilterChain#doFilter(), else it will call itself in an infinite loop.

Alternatively you can also just use an existing 3rd party API to do all the work for you, such as Tuckey's UrlRewriteFilter which can be configured the way as you would do with Apache's mod_rewrite.

BalusC
Any doFilter() sample code somewhere that does the above ? Thanks.
Frank
At what step exactly are you stucking? My answer almost writes code itself. Did you also note that the code references in blue are actually links to Javadocs which describes the class/method behaviour in detail? At any way, you can find [here](http://courses.coreservlets.com/Course-Materials/csajsp2.html) and [here](http://courses.coreservlets.com/Course-Materials/msajsp.html) good JSP/Servlet tutorials, specifically [this](http://courses.coreservlets.com/Course-Materials/pdf/msajsp/05-Filters.pdf) one about filters.
BalusC
+2  A: 

See this post it also has a Filter that does what you want

Romain Hippeau
A: 

You could use the ready to use Url Rewrite Filter with a rule like this one:

<rule>
  <from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
  <to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>

Check the Examples for more... examples.

Pascal Thivent