Daniel Kaplan
Daniel Kaplan

Reputation: 67440

In Jersey, how do I make some methods use the POJO mapping feature and some not?

I've got one resource (this is not a requirement) that has many different @GET methods in it. I've configured my web.xml to have this in it:

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

This turns on the POJO mapping feature which works great. It allows me to return a pojo and it gets automatically converted to JSON.

Problem is I've got some code I want to reuse that returns JSON as a String. I'm having trouble using these methods because Jersey does not interpret this as a JSON response, but as a String value to a JSON object. So if, for example, the method that returns a String returns an empty list the client sees

"[]"

instead of

[]

The problem is the JSON is wrapped in a double quotes. For these methods that return Strings, how can I tell Jersey to return the string as-is?

Upvotes: 3

Views: 3081

Answers (1)

futuretelematics
futuretelematics

Reputation: 1495

You probabily should have to use a custom response (or request) mapper.

1.- Create a class implementing MessageBodyWriter (or MessageBodyReader) in charge of writing / reading the response

@Provider
public class MyResponseTypeMapper 
  implements MessageBodyWriter<MyResponseObjectType> {
     @Override
     public boolean isWriteable(final Class<?> type,final Type genericType,
                final Annotation[] annotations,
                final MediaType mediaType) {
       ... use one of the arguments (either the type, an annotation or the MediaType)
           to guess if the object shoud be written with this class
     }
     @Override
     public long getSize(final MyResponseObjectType myObjectTypeInstance,
                     final Class<?> type,final Type genericType,
                         final Annotation[] annotations,
                     final MediaType mediaType) {
        // return the exact response length if you know it... -1 otherwise
        return -1;
    }
    @Override
    public void writeTo(final MyResponseObjectType myObjectTypeInstance,
                    final Class<?> type,final Type genericType,
                    final Annotation[] annotations, 
                    final MediaType mediaType,
                    final MultivaluedMap<String,Object> httpHeaders,
                    final OutputStream entityStream) throws IOException,                                                                 WebApplicationException {
        ... serialize / marshall the MyResponseObjectType instance using
            whatever you like (jaxb, etC)
        entityStream.write(serializedObj.getBytes());
    }
}

2.- Register the Mappers in your app

public class MyRESTApp 
     extends Application  {
    @Override
public Set<Class<?>> getClasses() {
        Set<Class<?>> s = new HashSet<Class<?>>();
        s.add(MyResponseTypeMapper.class);
        return s;
    }
}

Jersey will scan all registered Mappers calling their isWriteable() method until one returns true... if so, this MessageBodyWriter instance will be used to serialize the content to the client

Upvotes: 2

Related Questions