#421 ServletRunner fails for URL's that are served by filters

open
None
5
2008-12-01
2008-11-21
No

If you try to use ServletRunner to test web applications such as those implemented by Struts2, you can have a problem with URL's that are served by filters, not servlets. (Struts2 does this - its org.apache.struts2.dispatcher.FilterDispatcher filter detects and services struts2 actions without an underlying servlet being involved.)

The problem appears to be that the ServletRunner logic throws an exception if it can't find a servlet to match the URL before ever sending it through the filter chain. Thus, in this case, even though the filters are properly registered and would service the URL if applied, ServletRunner prematurely aborts trying to service the URL. A better solution, if possible, would be for the logic to look for the servlet only if the request made it through the filter stack - this is what real containers like Tomcat do.

A slightly ugly workaround is to map a dummy servlet to the URL pattern for these URL's. That makes ServletRunner happy (since it finds a servlet), but things still work because the filter gets processed first, and intercepts things before the dummy servlet is ever called.

The relevant portion of the exception stack trace (using HttpUnit 1.7) is shown below:

com.meterware.httpunit.HttpNotFoundException: Error on HTTP request: 404 No servlet mapping defined [ (THE URL BEING TESTED) ]
at com.meterware.servletunit.WebApplication$ServletRequestImpl.getServlet(WebApplication.java:772)
at com.meterware.servletunit.InvocationContextImpl$ExecutionContext.getServlet(InvocationContextImpl.java:248)
at com.meterware.servletunit.InvocationContextImpl.getServlet(InvocationContextImpl.java:86)
at com.meterware.servletunit.InvocationContextImpl.service(InvocationContextImpl.java:76)
at com.meterware.servletunit.ServletUnitClient.newResponse(ServletUnitClient.java:126)
at com.meterware.httpunit.WebClient.createResponse(WebClient.java:647)
at com.meterware.httpunit.WebWindow.getResource(WebWindow.java:220)
at com.meterware.httpunit.WebWindow.getSubframeResponse(WebWindow.java:181)
at com.meterware.httpunit.WebWindow.getResponse(WebWindow.java:158)
at com.meterware.httpunit.WebClient.getResponse(WebClient.java:122)

Discussion

  • Wolfgang Fahl

    Wolfgang Fahl - 2008-12-01

    Dear httpunit user!

    Thank you for your bug report. We appreciate the time and effort you are putting into this.

    Please supply a testcase with the expected result for the bug report that you are asking a solution for and we'll look into implementing it. For a start you might want to get the trunk version from the subversion repository (see https://sourceforge.net/svn/?group_id=6550\)
    and have a look at the source code of some of the more than 700 JUnit based testcase in there.

    If you do not use or have subversion tool you can still directly browse our test cases via:
    http://httpunit.svn.sourceforge.net/viewvc/httpunit/trunk/httpunit/test/com/meterware/httpunit/
    Looking into one or more of the Junit Java source files
    should give you a clue on what a proper testcase for httpunit looks like, often you will probably only have to "clone" an existing testcase and modify it slightly to your needs.

    When you are ready you might want to attach the testcase (and if you already have started implementing a solution for it it also the actual code) to the patch section of the sourceforge.net tracker for patches of the httpunit project at
    https://sourceforge.net/tracker/?atid=306550&group_id=6550&func=browse.

    The main communication about further details of the development is via the httpunit developer mailinglist. You are most welcome to sign up via
    https://lists.sourceforge.net/lists/listinfo/httpunit-develop

    Yours
    The httpunit developer team

    (Russell, Wolfgang, Mark, Patrick and Tim as of 2008-04)

     
  • Wolfgang Fahl

    Wolfgang Fahl - 2008-12-01
    • assigned_to: nobody --> wolfgang_fahl
     
  • Kevin Hunter

    Kevin Hunter - 2009-11-10

    Code demonstrating problem

     
  • Kevin Hunter

    Kevin Hunter - 2009-11-10

    I have attached a web project illustrates the problem.

    The class bugExample.ContentProvidingFilter is a servlet filter that
    actually returns content, in much the same way that the Struts2 filter does.

    In web.xml, this class is configured to respond to that url pattern "/filter/*".

    Thus, if you have this web app configured, and hit the URL
    http://server/context/filter/foo
    you get back the HTML that the filter generates.

    The class bugExample.ContentTest is a JUnit test using HttpUnit. It configures
    the web app to run under the "/test" context, and then attempts to access the
    URL http://localhost/test/filter/foo

    Instead of returning the content provided by the filter, as the system does in
    real life, instead an exception is thrown, because HttpUnit does not find a
    servlet mapped below that URL. (No servlet is necessary for this to work in
    a real application, because the filter "cuts off" the chain and serves the
    request itself, just the way that the Struts filter does.)

     

Log in to post a comment.