users@jersey.java.net

Re: [Jersey] Implementing a generic javax.ws.rs.core.Response

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 31 Mar 2009 16:47:51 +0200

Hi Jaka,


On Mar 31, 2009, at 4:36 PM, Jaka Jančar wrote:

> Hi Paul,
>
> Thanks for the tip, I'll try it.
>
> Are any changes planned in this area for the next JAX-RS spec version?
>

No yet.


> All of this would be, I think, acheivable in an easy way (without
> requiring the returning of anonymous subclasses) if
> MessageBodyWriter had another parameter that would receive the
> return type of the resource method, e.g. "Type
> resourceMethodReturnType", similar to how "annotations" receives
> it's annotations:
>
> boolean isWriteable(
> java.lang.Class<?> type,
> java.lang.reflect.Type genericType,
> java.lang.annotation.Annotation[] annotations,
> java.lang.reflect.Type resourceMethodReturnType, /* NEW */
> MediaType mediaType)
>
> This would be analogous to genericType parameter in
> MessageBodyReader, which receives the type of the parameter. It
> would differ from genericType in MessageBodyWriter in that it would
> always get the return type of the method and never do runtime
> inspection, but instead let the provider infer the type on its own.
> Basically doing less than what is done now for genericType.
>
> If you look at table 3.1 of the spec, you'll see that columns 2, 3
> and 4 are available to MessageBodyWriter, but the first one really
> isn't, which is exactly what resourceMethodReturnType would provide.
>
> What do you think?
>

Responses may also be "returned" by throwing exceptions. Thus the
introduction of a new parameter specific to a resource method, which
will not apply in all cases, introduces an inconsistency.

IMHO given the inconsistency and the anonymous class work around i do
not think there is enough justification to change the API.

Now, if you could solve the builder problem to build a generic
response (safely according to the type) then that would be something
to consider in terms of changing the API.

Paul.



> Jaka
>
>
> On 30. Mar 2009, at 18:24, Paul Sandoz wrote:
>
>>
>> On Mar 30, 2009, at 6:12 PM, Jaka Jančar wrote:
>>> Is this problem solvable without modification of Jersey? You said
>>> that you gave up on generic Response because of the builder
>>> pattern. I don't mind not using ResponseBuilder. Doing "return new
>>> MyResponse(code, headers, entity);" is acceptable to me.
>>>
>>> All I can think of is doing reflection of type within my resource
>>> methods and passing that to MyResource. Or, alternatively, passing
>>> the Method to MyResponse and then doing the reflection there. But
>>> this is all very ugly.
>>
>>
>> Try doing something like the following:
>>
>> public class MyResponse<T> extends javax.ws.rs.core.Response {
>> Type t;
>> T e;
>>
>> MyResponse(T t) {
>> t = getSuperclassTypeParameter(getClass());
>> }
>>
>> Object getEntity() {
>> return new GenericEntity(e, t);
>> }
>>
>> // This code is copied from the implementation of GenericEntity
>> private static Type getSuperclassTypeParameter(Class<?>
>> subclass) {
>> Type superclass = subclass.getGenericSuperclass();
>> if (!(superclass instanceof ParameterizedType)) {
>> throw new RuntimeException("Missing type parameter.");
>> }
>> ParameterizedType parameterized = (ParameterizedType)
>> superclass;
>> return parameterized.getActualTypeArguments()[0];
>> }
>>
>> ...
>> }
>>
>> It requires that you create an anonymous class e.g.:
>>
>> @GET
>> public MyResponse<Bean> get() {
>> Bean b =
>> return new MyResponse<Bean>(b) {};
>> }
>>
>> Paul.
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>