On Mar 30, 2009, at 4:46 PM, Jaka JanĨar wrote:
> Hi!
>
> (disclaimer: this isn't really a question, just a request for
> comments of the idea)
>
> I want my resource methods to:
> a) return strongly typed entities (so entity types can be specified
> in interfaces), and
> b) have the ability to set status code, headers, etc.
>
> Returning Response violates (a), returning Other (in JAX-RS section
> 3.3.3 terms) prevents (b).
>
> Ideally, I would like my resource method to look something like this:
>
> @GET
> @Path("/person")
> MyResponse<Person> getPerson();
>
BTW we tried really hard to make Response generic, but gave up because
we could not make the generic type work correctly with the builder
pattern.
> So I thought about defining MyResponse as:
>
> public class MyResponse<T> extends javax.ws.rs.core.Response {
> public void setEntity(T entity) {...}
> public T getEntity() {...}
> ...
> }
>
> (btw, I think it's ugly that Response is an abstract class instead
> of an interface)
>
An abstract class was chosen because it makes it easier to extend
without breaking backward compatibility and it has the static builder
methods.
> But if I understand JAX-RS (table 3.1 in particular) correctly, this
> would break generic type recognition (it would fall in the 3rd row
> category), which I need in my entity providers.
>
> So the only solution, it appears, would be to define MyResponse in
> such a way that it would return GenericEntity:
>
> public class MyResponse<T> extends javax.ws.rs.core.Response {
> private T entity;
>
> public void setEntity(T entity) {...}
> public GenericEntity<T> getEntity()
> {
> return new GenericEntity<T>(entity) {};
> }
> ...
> }
>
> Does anyone see any problems with this?
>
Yes, you are not setting the genericType when creating the
GenericEntity thus things will not work for:
MyResponse<List<Bean>>
> A concern I have is that, because I would like to stay Jersey-
> independent, I would have to implement MultivaluedMap (for
> Response#getMetadata()), but the implementations in Jersey seem to
> do much more than the trivial implementation of the interface, so
> I'm worried that something will break.
>
Note that the returned map may be modified by the runtime. Jersey's
implementation ensures that keys are case insensitive. If you do not
support case-insensitive keys things could be problematic.
I recommend you do the following. Create a dummy Response and use the
MultivaluedMap instance from that e.g.
Response.ok().build().getMetadata()
Paul.