users@jersey.java.net

Re: [Jersey] _at_FormParam, Servlets and x-www-form-urlencoded

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 19 Jan 2009 12:02:59 +0100

Hi Samuel,

You have correctly diagnosed the issue and i have been discussing the
same issue here:

   http://markmail.org/search/?q=list
%3Anet.java.dev.jersey.users#query:list%3Anet.java.dev.jersey.users
+page:1+mid:ycsknkgspo7svvv2+state:results


I would really like to come up with a solution that could work under
some circumstances at least, namely when JAX-RS applications use
@Form. As i said in the email thread linked to above there are certain
cases that are not possible to support because the request entity
cannot be reproduced.

It seems a solution as follows might be acceptable:

   1) The servlet layer checks the form media type;
   2) If 1) is true then it checks oif the request entity is empty (or
consumed);
   3) if 2) is true then it gets the servlet request parameters and
subtracts
       any parameters declared in the query string using Jersey query
parsing.
   4) The remaining parameters are added to a Form instance which is
        added as a special property of the HTTP request.
   5) When form parameters are processed the special request property
is first
        checked to see if a value is present, of so the Form instance
that is the value
        is used.

Does that sound like a reasonable solution?

Note that i do think that Servlet is broken in this respect. It makes
it impossible to correctly layer on top of servlet, or layer filters.
So we have to work around it.

Paul.


On Jan 19, 2009, at 2:12 AM, Samuel Le Berrigaud wrote:

> Hi all,
>
> we are experiencing an interesting issue and I hoped that someone
> would have had a similar problem and could help. Here it is.
>
> We deployed a Jersey servlet
> (com.sun.jersey.spi.container.servlet.ServletContainer) into our
> application. We have a service that makes use for @FormParam.
> So when using the Jersey client we do something like:
>
> final Form formData = new Form();
> formData.add("param1", "value1");
> final MyResource resource =
> Client.create().resource("http://localhost:8080/
> rest").path("myresource").post(MyResource.class,
> formData);
>
> on the server side we try to get the value of the param1 like so:
> @FormParam("param1") String param1
>
> Nothing complicated here. However on the server side param1 is always
> when we use that code. Here is the reason why.
>
> The Jersey client generated request has its content type set to
> "application/x-www-form-urlencoded" which is the correct content type
> for HTTP POSTs that have a body of url encoded params. However in our
> application we have several filters, some of which access the request
> parameters through one of the ServletRequest#getParameter* methods.
> This means that the application server (I tested on Tomcat 5.5 and
> Jetty 6.1) will consume the request input stream to access the
> parameters and leave it empty.
> So when Jersey tries to parse the request body it finds it to be
> empty. Hence our param1 being null.
>
> I understand that Jersey needs to access the request body to parse
> those parameters as JAX-RS differentiates FormParameters from Query
> Parameters, where the Servlet Spec doesn't. But is seems to me that it
> makes JAX-RS and the Servlet Spec incompatible. Or am I missing
> something that would make both work happily together?
>
> Thanks,
> Samuel Le Berrigaud.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>