users@jersey.java.net

Re: [Jersey] Returning basic data types in Jersey

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 05 Jun 2008 10:16:49 +0200

Hi Rohan,

Rohan Sahgal wrote:
> I was just about getting started with Jersey.
> I went through the examples in the distribution.
>
> I have one question though, how do you return a basic data type(such as
> int,float,double,etc) when you use Jersey.
> I see a couple of examples for returning custom data types (Entity
> Provider and JsonFromJaxb) but how do I go about returning an int
> without converting it to a String.
>

JAX-RS and Jersey do not support the returning of primitive types, for
two reasons: 1) what should be the media type?; and 2) if it is
converted to a sequence of say UTF-8 encoded characters what should be
those characters (we did not want to pull in the XSD datatypes
specification!).


> Specifically I was thinking of exposing some counters through Jersey so
> that they can be accessed elsewhere. Now all these counters have a get
> that returns an int, how do i annotate them to make it work in jersey. I
> cant change the method signature because some other code already calls
> these get methods.
>
> Any help will be highly appreciated.
>

You can support writing of your own data types using a message body
writer. Off the top of my head you might be able to do this:

@Provider
public class PrimitiveWriter implements MessageBodyWriter<Object> {
     public boolean isWriteable(
             Class<?> type,
             Type genericType,
             Annotation annotations[]) {
        return type.isPrimitive();
     }

     public void writeTo(
             Object t,
             Class<?> type,
             Type genericType,
             Annotation annotations[],
             MediaType mediaType,
             MultivaluedMap<String, Object> httpHeaders,
             OutputStream entityStream) throws IOException {
         entityStream.write(t.toString().getBytes());
     }

     public long getSize(Object t) {
        return -1;
     }
}

but you might have to watch out for autoboxing.

Alternatively you could have a message body writer that works with
instances of Number:

@Provider
public class PrimitiveWriter implements MessageBodyWriter<Number> {
     public boolean isWriteable(
             Class<?> type,
             Type genericType,
             Annotation annotations[]) {
        return Number.isAssignableFrom(type);
     }

     public void writeTo(
             Number t,
             Class<?> type,
             Type genericType,
             Annotation annotations[],
             MediaType mediaType,
             MultivaluedMap<String, Object> httpHeaders,
             OutputStream entityStream) throws IOException {
         entityStream.write(t.toString().getBytes());
     }

     public long getSize(Number t) {
        return -1;
     }
}


If using Jersey's class scanning or package scanning deployment make
sure that the writers are placed in locations that are scanned (just
like root resource classes).

Hope this helps,
Paul.


-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109