Showing posts with label filter. Show all posts
Showing posts with label filter. Show all posts

Monday, November 15, 2010

Jeans - Running Java Servlet and JSP Webapp in ASP.NET/IIS - Part 3

Developing Java webapp, we use of Filter for cache control, compression, database connection and transaction handling. So, Filter is another feature I need to support.

Original Thought
In ASP.NET, IHttpModule is like a filter while IHttpHandler is like a servlet. It seemed obvious to modify the existing ServletModule to execute the filter.

Platform Mismatch
The first problem I found is the async design of ASP.NET. The IHttpModule is an event sink and need to implement the event handlers for events like BeginRequest, EndRequest. In contrast, Servlet Filter is using FilterChain to call the filter one by one. I tried to execute the filter chain in BeginRequest event. However, I won't be able to gain the access of Session. Having google around, I found the comprehensive events execute sequence in IHttpModule (http://msdn.microsoft.com/en-us/library/ms178473.aspx):
  • BeginRequest
  • AuthenticateRequest
  • PostAuthenticateRequest
  • AuthorizeRequest
  • PostAuthorizeRequest
  • ResolveRequestCache
  • PostResolveRequestCache
  • PostMapRequestHandler
  • AcquireRequestState
  • PostAcquireRequestState
  • PreRequestHandlerExecute
  • PostRequestHandlerExecute
  • ReleaseRequestState
  • PostReleaseRequestState
  • UpdateRequestCache
  • PostUpdateRequestCache
  • EndRequest
  • PreSendRequestHeaders
  • PreSendRequestContent
    To get the session, the module needs to implement an event handler for PostRequestHandlerExecute event. In order to get the Session, HttpContext.Current.Handler has to be implementing IRequiresSessionState as well.

    There is code to wrap the HttpContext.Current.Handler around (http://stackoverflow.com/questions/276355/can-i-access-session-state-from-an-httpmodule). It worked fine but it does not solve the async problem.

    From Module to Handler
    I managed to run the filter chain in PreRequestHandlerExecute event. It turned out that not only it run the JSP code, but also the source code of the JSP was also append to the result by the default handler. Response.End() has to be invoked. And then some checking for the whether it is my own servlet handler, etc. The code is a bit weird.

    Since it does not matter where the filter chain is executed, I moved to code to ServletHandler and revert the changes in ServletModule, it compiled and seemed working with the Hello World JSP. No more Response.End() and checking. Async problem is solved since executing the filter and servlet are in one place. It matched the semantics of Java webapp.

    Testing
    The simplest way to test is to get a filter that GZIP the output and use fiddler to see if the response is compressed. I grabbed filter from http://onjava.com/pub/a/onjava/2003/11/19/filters.html. Added the setting in web.xml. Somehow it does not work. It turned out it's because the default XML namespace in web.xml generated by Eclipse caused the problem. Removing the namespace made enabled the support of filter.

    XML Namespace
    The default XML namespace is quite annoying. I am not sure why it is there as it is meaningless. I tried a few way to remove it with the .Net XML API but the namespace somehow stayed there. The final resort was invoking string.Replace() to get rid of it.

    The latest source code has been checked-in in http://jeans.codeplex.com/.

    Friday, December 15, 2006

    Base64, MHTML, and IE

    In HTML 4.0, binary objects (e.g. image) can be inlined with Base64 encoding. However, Internet Explorer totally ignores the standard. Even in IE7, base64 image is still not supported.

    Two solutions proposed by Dean Edwards and Luiz Angelo De Luca are trying to solve the problem. Both of them are implemented in PHP. Base64Html is a Java implementation of Luiz Angelo De Luca's solution: convert the HTML into MHTML (HTML Mail format).

    Luiz Angelo De Luca's solution can be genernalize to the following steps:
    1. Buffer the output and add a function callback
    2. If the browser is IE, set the HTTP header to MHTML
    3. Convert the HTML to MHTML
    Luiz Angelo De Luca has implemented it in a single PHP. In Java, we make use of HttpServletResponseWrapper (for #1), Serlvet Filter (for #2), and Apache Jakarta Commons Email API (for MHTML construction). Source code and example web app are available at: http://www.shaneng.net/Main/Base64Html