users@jersey.java.net

Re: [Jersey] Setting Response Status

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 18 Mar 2010 09:26:46 +0100

Hi Moises, Charles,

This is certainly easy to implement and experiment with using a
ResourceFilter. So this should not block yourself or Charles from
implementing something like this. The question i am asking myself is
whether this should be part of Jersey, not sure yet :-)


The not modified approach is a little more complicated as the status
code is dependent on what is in the request, the precondition related
headers, and what state is held by the server. So you could, as you
present, declare the set of possible status codes, but the status code
still needs to be declared in at least one case, thus requiring one to
declare a return type of Object or Response. I think improved ease of
use pre-condition support may require a higher-level concept.


For the created case perhaps it is better to return an instance of
Created<DomainType> that encapsulates the URI. One reason being is the
representation returned from the POST request may be different from
the representation returned from a GET request to the URI in the
Location header. They are only the same if the server responds with
Location and Content-Location headers that have the same URI value.

So I am wondering if instead of annotations (placing aside the
documentation aspects for this point) we could do the following instead:

1) a way of making Response generic, requires a new set of classes
unfortunately;

2) an easy way of extending a generic Response and building of.

Paul.

On Mar 18, 2010, at 5:12 AM, Moises Lejter wrote:

> On the other hand, I think it would be great to have something like:
>
> @POST @Created
> @Produces({"application/xml"})
> DomainType getterFunction( ... ) { ... }
>
> with classes that implement
> interface UriMapper<Type> {
> URI getURI(Type result, UriInfo requestURI);
> }
>
> so that Jersey can automatically change the status code of the
> function
> from OK to CREATED *and* call the appropriate URI for the Location
> header from the return value automatically. (Response.created() is
> already a special case of status code with built in Location header,
> it would just be replicated in the @Created annotation).
>
> We could also have
>
> @POST @Status({OK,CREATED,...})
> Response resourceMethod( ... ) { ... }
>
> to document what the set of possible status codes returned from the
> method
> is (which is currently impossible to get at declaratively), and even
>
> @POST @Status({NOT_MODIFIED})
> DomainType getterFunction( ... ) { ...; return obj; }
>
> which would be equivalent to
>
> @POST
> Response getterFunction( ... ) {
> ...
> return Response.status(NOT_MODIFIED).entity(obj);
> }
>
> (so a @Status with a single possible status code would automatically
> set the status code to the one code listed in the value list, while
> setting
> the body entity to the return value).
>
> All of these have the virtue of capturing declaratively information
> that would not have been known otherwise, I think they are all easy
> to do,
> and they might help with the automatic documentation of JAX-RS
> resources?
>
> Moises
>
> On Mar 17, 2010, at 8:17 PM, Charles Overbeck wrote:
>
>> Hi Paul,
>>
>> Thanks again for your quick response.
>>
>> You're right about the Location header, which I had in the back of
>> my mind; maybe a little too far back :). So that does argue against
>> the filter.
>>
>> I just wanted to make sure there wasn't another way of doing things
>> that I was missing. I'll just go with returning a Response.
>>
>> Charles
>>
>>
>>
>>
>> ----- Original Message ----
>> From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
>> To: users_at_jersey.dev.java.net
>> Sent: Wed, March 17, 2010 1:22:39 AM
>> Subject: Re: [Jersey] Setting Response Status
>>
>> Hi Charles,
>>
>> Unfortunately the usual way to do this is to return a Response
>> instance and then the method signature is not preserved:
>>
>> URI u = ...
>> Response.created(u).entity(new
>> GenericEntity<JAXBElement<newlyCreatedCurrency>>(newCurrency) {}).
>> build();
>>
>> Usually a 201 response should have a Location header. If not you
>> can just do:
>>
>> Response.status(201).entity(new
>> GenericEntity<JAXBElement<newlyCreatedCurrency>>(newCurrency) {}).
>> build();
>>
>>
>> An alternative way if you are just interested in declaring the
>> status code is to write a resource filter and define your own
>> annotation, say Status, that you can annotate on your resource
>> method. The resource filter would check if such an annotation is
>> present and modify the status code accordingly.
>>
>> But note as pointed out 201 should also have a Location header, so
>> i am not sure the 201 created use-case benefits from declaring the
>> status code.
>>
>>
>> Note that the reason why GenericEntity is requires is because at
>> the time we could not work out how to make Response generic, we now
>> know how to do that, and it is something that should be fixed in
>> any JAX-RS 2.0 effort and an i am inclined to implement a Jersey
>> specific solution in the interim.
>>
>> Paul.
>>
>> On Mar 16, 2010, at 6:24 PM, Charles Overbeck wrote:
>>
>>> Hello,
>>>
>>> I have code like this:
>>>
>>> @POST
>>> @Produces("text/xml")
>>> @Consumes("text/xml")
>>> public JAXBElement<CurrencyType> addCurrency(CurrencyType
>>> newCurrency) {
>>> ...
>>> return <JAXBElement<newlyCreatedCurrency>, where
>>> newlyCreatedCurrency may not be exactly the same as newCurrency>
>>> }
>>>
>>> Because I am doing a create, I want the HTTP status response code
>>> to be 201, but it is 200.
>>>
>>> Is there any way I can set the response code to 201, preserving
>>> the above method signature?
>>>
>>> I know that I can change the method to return a Response, and use
>>> ResponseBuilder.status() to explicitly set the status. Previously
>>> I was doing that, and all my method signatures returned Reponses.
>>> I've since been changing my resource methods to not return
>>> Reponses, but the actual type of the entity. The code reads
>>> better, and there are tools that can generate better documentation
>>> for my REST API.
>>>
>>> Are there just some cases, like this one, where I'm going to have
>>> to return a Reponse, or is there a way to set the status code here?
>>>
>>> Digression: I haven't actually tried any of the documentation
>>> tools, and maybe Jersey itself offers something, but briefly
>>> looked at the enunciate web page, which looks like it could
>>> generate good doc. Does anybody have any experience/
>>> recommendations for generating docs for their REST API?
>>>
>>> Thanks,
>>>
>>> Charles
>>>
>>>
>>> ---------------------------------------------------------------------
>>> 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
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>