Hi Dan,
Craig makes some very good points.
The underlying reason why this does not work is you a defining that a
JAXB object Request be created from the request entity. Because there
is no entity present you will be getting a JAXB unmarshalling
exception that results in a 400 response.
There are cases, for example when interoperating with WebDAV clients,
where one needs to manage the case of an empty or non-empty request
entity. You can use EntityHolder for that:
https://jersey.dev.java.net/nonav/apidocs/latest/jersey/com/sun/jersey/core/provider/EntityHolder.html
I think we should add a PATCH method to Jersey and also try to add
support for the Accept-Patch header for OPTIONS:
http://tools.ietf.org/html/rfc5789#section-3.1
Paul.
On Jun 8, 2010, at 12:07 AM, Craig McClanahan wrote:
> On Mon, Jun 7, 2010 at 2:49 PM, danomano <dshopkins_at_earthlink.net>
> wrote:
>>
>> I have a requirement to implement an api as follows:
>>
>> PUT
>> ../resource/<id>
>> <body is payload>
>>
>> Result: new resource is created (error is resource already exists)
>>
>> PUT
>> ../resource/<id>?someField=abc
>> <NO BODY>
>>
>> Result: update the resource such that someField = abc.
>>
>> I tried mapping this as follows:
>> @PUT
>> @Path("/{resourceId}")
>> public void createOrUpdate(Resource resource,
>> @PathParam("resourceId") String
>> resourceId,
>> @QueryParam("someField") Long
>> someField);
>>
>> however this only appears to work if the Resource payload is
>> present, i.e.
>> if I do an HTTP PUT, without a payload the method is never invoked.
>>
>> I tried mapping as well to 2 seperate methods, one with payload
>> (minus the
>> queyParam), and one without the playload but with the queryParam,
>> but that
>> was ambigious for jersey..so that didn't work)
>>
>> Is this mapping not possible?
>> (and yes I argued the user should be forced to issue put-update
>> calls with
>> the payload rather then the queryparam..but got overruled).
>>
>> Any advice? (Am I going be stuck with using servlets as my
>> interface?..yuk..I could inject an empty <Resource/> I suppose with a
>> servletFilter..)
>
> Several things to think about:
>
> (1) Per RFC 2616 Section 9.4[1], a PUT with no body violates the
> HTTP spec,
> so it's hard to be sympathetic with a complaint that a framework
> like JAX-RS doesn't support that use case.
>
> (2) Even if you moved the "someField=abc" into the body, using
> PUT for partial updates also violates the intent of PUT as defined
> in HTTP. For partial updates, consider using the PATCH method,
> which was recently standardized[2]. (You'll have to define your
> own annotation for it with current versions of JAX-RS, but its
> easy).
>
> (3) In RFC 2616, Section 9.1, requirements for idempotent requests
> are described -- in particular, the fact that an idempotent can be
> repeated by the client with no negative side effects. The problem
> with using PUT for resource creation is that PUT is required to be
> idempotent, so it is difficult to enforce this requirement
> unless there
> is some unique identifier within the resource body that will cause
> a duplicate create request to get caught, and thus avoid creating
> two or more records. POST is generally easier to deal with in
> this
> regard, although you still need to figure out what happens when a
> client, say, doesn't receive any response to an initial POST and
> therefore tries it again. (This, by the way, is why browsers
> warn you
> when you use the back arrow and then try to submit a form using
> POST again.)
>
> [1] http://www.ietf.org/rfc/rfc2616.txt
> [2] http://www.ietf.org/rfc/rfc5789.txt
>
>>
>> thanx
>> Dan
>
> Craig
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>