users@jersey.java.net

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

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 20 Jan 2009 10:50:41 +0100

On Jan 20, 2009, at 1:29 AM, Samuel Le Berrigaud wrote:

> 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 will attempt to fix it for the 1.0.2 release, which will happen in
about 2 to 3 weeks, so it should be in the 1.0.2-SNAPSHOT earlier than
that. Can you log an issue and after i fix it verify?

I think it best to try and support this without any requirement on the
developer to configure anything, it could be implemented as a Jersey
filter which is added by the Jersey servlet as you indicate. As you
say we can log a warning when the Jersey servlet detects such a case
to indicate that only @FormParam can be used under such conditions.

Paul.

> 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.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>