users@jersey.java.net

[Jersey] Re: PostReplaceFilter does not get parameters from body

From: Ferdy Nagy <ferdy.nagy_at_pobox.com>
Date: Mon, 15 Dec 2008 13:23:26 -0800

Thanks Paul, specifically I'm doing this to support ActionScript/Flash
applications that have a restriction where they cannot set the headers for
anything other that POST, so they need to use the override header to make it
a GET, but, if the URL contains any query parameters it automatically
reverts back to GET and drops any custom headers - you really have to admire
the genius behind some of the actionscript libraries. Another reason I want
to support sending parameters in the body via POSTing a GET is that the
query parameters may be long and the url may become unwieldy or max out
(GData also supports parameters in the body).

My resource is still fundamentally a GET, which also takes POST (create),
and PUT (update) so using POST with an @FormParam would break the REST
paradigm. I don't think it's unreasonable to expect that using the
X-HTTP-Method-Override to coerce into GET that the parameters should be
available as though it was an actual GET request - but I do agree that the
parameters are in the body which goes against the grain of GET being uri
based; then again, so does the override header.

>> I'm using a PostReplaceFilter so that a caller can GET a resource
>> via a POST operation, which works fine; however parameters sent in
>> the body with content-type: application/x-www-form-encoded are not

>> available, they're always empty in the parameter map. It works if
>> the parameters are included in the query string.
>>
>
>When you say "parameter map" what are you referring to? Can you share

>some code?

@GET
public Response get(@PathParam("entityId") Integer eid, @Context
HttpServletRequest req) {

  // Some of the parameters follow a pattern, like param.1.XX or param.2.XX
so I need to
  // have access to the parameter map directy

  // This will always be an empty enumeration when using the replace filter
with the parameters
  // in the body
  Enumeration<String> names = req.getParameterNames();

  // Using the UriInfo getQueryParameters is also empty - presumably for the
same reason the
  // ServletRequest parameters are also null
}


>It seems as if you want to do something very specific and convert form

>parameters of a POSTed request entity into query parameters of the
>request URI, is that correct?


I added this to the PostReplaceFilter and it works like a charm; I think
this is something that most people would want if they are employing the
method override...

        // If we got some parameters encoded in the body for this override
GET request
        // pull them out and add them to the query.
        String contentType =
request.getRequestHeaders().getFirst("Content-Type");
        if ("GET".equalsIgnoreCase(override) &&
MediaType.APPLICATION_FORM_URLENCODED.equals(contentType)) {

            Form form = request.getFormParameters();

            if (form.size() > 0) {
                UriBuilder builder = request.getRequestUriBuilder();
                Set<Map.Entry<String, List<String>>> entries =
form.entrySet();

                for (Map.Entry<String, List<String>> entry:entries)
{
                    builder.queryParam(entry.getKey(),
entry.getValue().toArray());
                }

                request.setUris(request.getBaseUri(), builder.build());
            }
        }


Jersey is a really nice implementation, the ability to easily leaverage the
IoC and create custom injected properties along with the provider mechanism
is great; well done!

- Ferdy