users@jersey.java.net

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

From: Jaka Jančar <jaka_at_kubje.org>
Date: Tue, 31 Mar 2009 16:36:54 +0200

Hi Paul,

Thanks for the tip, I'll try it.

Are any changes planned in this area for the next JAX-RS spec version?

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?

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
>