Accessing to request.body() from multiple filters

950 views
Skip to first unread message

Jon Mirakul

unread,
Sep 7, 2014, 12:03:53 PM9/7/14
to spar...@googlegroups.com
I 'am using Spark version 1.11 because of Java 7 limit and I've problem accessing to request body from Spark.before filters and that in the main filter Spark.post. If I access to request body from the before filter and after that in the Spark.post filter handle method i'am getting empty string from request.body(). I know that servletrequest's inputstream can be consumed only once. So, Is it possible for Spark to send same spark request instance as argument to before filter handle method and after that to any Spark.xxxx filter handle method?
In that case consumed body in before filter will be available to any subsequent filter.

a platypus

unread,
Sep 17, 2014, 9:55:32 AM9/17/14
to spar...@googlegroups.com
Hi Jon and others ...

I have been wrestling with this challenge with filters for a couple of days now.  Here's a simple use-case:
  1. HTML  web page (test.html).
    • One input field ("name")
    • Method = Post
  2. Before filter (this checks authentication)
    • before( "/post/details", authenticator )
    • Looks at session and tests if authenticated.
    • When "YES" ... pass through to the "/post/details" handler.
  3. Log file output:
    • Authenticator:
      • pathInfo:        /post/details
      • Parameters:  "name=George&save="  ( this is: request.body() )
      • authenticated == true, so:
      • set response body as follows:  response.body( request.body() );
        • I got the idea for this by stepping through the filter code with the debugger (details below).
    • /post/details handler:
      • pathInfo:        /post/details
      • Parameters:  null  ( this is: request.body() )
  4. Result my update fails.

Looking in Spark -- MatcherFilter.doFilter( ... ):  Observe line #88.  (Line numbers may differ depending on which version of the source you are looking over).

  • String bodyContent = null;

The before filter(s) check the response.body() content after each filter finishes.  Witness, line #112

  • String bodyAfterFilter = Access.getBody(response);
    if (bodyAfterFilter != null) {
        bodyContent = bodyAfterFilter;
    }

Once I saw this, filters started to make more sense for me.  Each filter can make changes and pass the result, like a relay-baton to the next handler.  Looking further down the page in the same method, around line #135, some place around the line highlighted below I believe Spark needs to transfer the bodyContent to the newly created Request instance.

  •  if (target != null) {
        try {
            String result = null;
            if (target instanceof RouteImpl) {
                RouteImpl route = ((RouteImpl) target);
                Request request = RequestResponseFactory.create(match, httpRequest);  // label: [A]
                Response response = RequestResponseFactory.create(httpResponse);

                req.setDelegate(request);
                res.setDelegate(response);

                Object element = route.handle(req, res);

                result = route.render(element);
                   // result = element.toString(); // TODO: Remove later when render fixed
            }
        }//end-try...
I was thinking something like:

if( null != bodyContent )
{
   response.body( bodyContent );
}

In that way, the content changes or transformations from "filters" would propagate forward.  If not, then my naive expectation was for the request passed to my "post/details" handler to have the original body content from the HTML page.  Unfortunately, the newly created request (label [A]) from the snippet above has a null body content. 

I suggest that this is a big problem with filters.  Until there's a code-update or a fix push-ed through the only thing before filters can be used for is is to redirect URL-s to different pages or check for errors like 404, etc.  Take care about what you'd like to do with filters, the feature as written doesn't suit my use-cases where I'd like a filter (esp. authentication).  Which is a great pity imho. 

I'm going to check the GitHub to see if there's work in progress.  I've posted here because it will save folks days of debugging effort to skip-by filters until there's a better way to process chained requests.  It may not be a 'bug' -- Another reason to write something here first.  As the documentation is minimal on this, I can't say how you're supposed to use filters for real applications, my assumptions/expectations may be off-base.

I'd like to hear if others have a more effective pattern for filtering, transforming and chaining requests. 

Also I got a couple of InvalidStateExceptions while looking at filters.  It would be good if one of you knows where the state changes happen along the data pipeline.

I'll be very interested to hear comments and suggestions.  Oh yes, I was using Spark 2.0.0 and Java 8.  I notice Jon's question is about Java 7 so the challenge is with us.  Thanks for listening, comments most welcome.

Kind regards,

  Will

it....@kartoffelkombinat.de

unread,
Apr 9, 2017, 3:08:11 PM4/9/17
to sparkjava
Hi,

I'd like to push this thread since I am experiencing the problems described by Will in the most recent Spark version 2.5.5. In my setup, I use spark-pac4j (version 2.0.0-RC2) for authenticating the users of my app and I'm seeing the exact same behaviour Will analysed for his setup: the body content gets lost along the way when passing through the security filter. Everything works fine when I disable the filter.

I described the details inc. code snippets in this SO question, which has not received any answers yet unfortunately. I'm hoping to be more lucky here. Any help would be much appreciated.

Thanks,
Uwe

KK IT

unread,
Apr 24, 2017, 8:54:51 AM4/24/17
to sparkjava
I found the answer, the mistake was on my side. I should have used the request's queryParams() method to get the desired values instead of parsing the request's body manually. A working code snippet in on SO.
Reply all
Reply to author
Forward
0 new messages