users@jersey.java.net

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

From: Samuel Le Berrigaud <samuel.lb_at_gmail.com>
Date: Wed, 21 Jan 2009 09:14:39 +1100

Hi Paul,

a fix for the 1.0.2 release would be great. I have created the issue
at: https://jersey.dev.java.net/issues/show_bug.cgi?id=188 and am
happy to verify when fixed.

SaM

On Tue, Jan 20, 2009 at 8:50 PM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
> 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
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>