users@jersey.java.net

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

From: Samuel Le Berrigaud <samuel.lb_at_gmail.com>
Date: Tue, 20 Jan 2009 11:29:30 +1100

Hi Paul,

after having thought a bit more about the issue I couldn't figure out
a solution that would comply with the Servlet Spec. and wouldn't
require an additional servlet Filter at the very top of the chain to
wrap the request in some way.

Your solution would definitely work around the issue. This is probably
not ideal but I don't see any better solution right now and it seems
pretty reasonable. Would you implement that as Jersey request filter?
When could it be planned? How could I possibly help?

I think at the very least Jersey should issue a warning when
processing a POST request with url encoded content type and an empty
request input stream. This could be a quick thing to implement if
getting a proper solution in place would take more time.

SaM

On Mon, Jan 19, 2009 at 10:02 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
> 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.