users@jersey.java.net

Re: [Jersey] Questions about 'templated' content responses and return type (url param)

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 23 Jan 2009 14:29:14 +0100

On Jan 23, 2009, at 1:52 PM, amsmota_at_gmail.com wrote:

> Far from me the idea of suggesting that this framework is better
> than the other, as they all have their merits and are good in the
> specific cases for they were build for.
>

Suggest by all means! such discussion is really useful.


> That being said, your use case seems a strong candidate to be used
> by Spring Integration, as you can have your "normal logic" of
> getting "concrete data based on java object type" and just wrap it
> in the endpoints with Message Transformers.
>
> Or, as is my actual case, use Jersey for the connectors/resources
> side and Spring Integration handling the Messaging to and from the
> server "service implementations" including the transformations and
> wrapping and etc...
>

If you want to leverage message transformation with JAX-RS then you
can wrap the returned entity around another Java type for which there
is a message body writer. The writer for that type can defer to the
JAX-RS Providers to write the actual wrapped object. This is a nice
approach because it means you can use all the existing JAX-RS
infrastructure for writing (like JAXB etc). This technique is also
used for Multipart MIME and Atom support, both of which are
essentially different forms of enveloping syntaxes.

If one does not want to modify the application code to wrap then this
could be performed using say Spring AOP to adjust returned instance.
Or one can use a Jersey specific resource filter to modify the entity
instance. An example of the latter follows:

public class WrapperFilterFactory implements ResourceFilterFactory,
ResourceFilter, ContainerResponseFilter {

     // ResourceFilter

     public ContainerRequestFilter getRequestFilter() {
         return null;
     }

     public ContainerResponseFilter getResponseFilter() {
         return this;
     }

     // ContainerResponseFilter

     public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {
         if (response.getEntity() == null) return;

         Wrapper w = new Wrapper(response.getEntity());
         response.setEntity(w);
     }

     // ResourceFilterFactory
     public List<ResourceFilter> create(AbstractMethod am) {
         if (am instanceof AbstractResourceMethod) {
             if (am.isAnnotationPresent(Wrap.class) ||
am.getResource(). isAnnotationPresent(Wrap.class)) {
                 return Collections.singletonList((ResourceFilter)this);
             }
         }

         return null;
     }
}


@Wrap // wrap objects returned by resource methods
@Path("/")
public class MyResource {

    public @GET JAXBBean get() {
        ....
    }
}



Using an AOP-based approach requires that you do something like this
in the wrapping method:

     Object returnInstance = ...
     if (returnInstance instanceof Response) {
        Response r = (Response)returnInstance;
        Object entity = r.getEntity();
        return new Wrapper(Response.fromResponse(r).entity(e).build());
     } else {
         return new Wrapper(returnInstance);
     }


Paul.



> Hope it help.
>
>
>
>
> On Jan 22, 2009 4:51pm, Matthew Camuto <mattcamuto_at_gmail.com> wrote:
> > Hi There -
> >
> > I am fairly new to jersey and have been loving what I see so far.
> However I have a few questions about about current needs at work.
> >
> > We are developing api's at work and have a few requirements that
> are desired. One that is that ever response would essentially be a
> 'template' if you will with some common information (think term of
> service, error codes). I realize that jersey is very 'pojo' and was
> not sure if this would be trivial to implment.
> >
> >
> > For example we would want all of our api responses to look like
> something like this:
> >
> >
> > TERM OF SERVICE FOR ALL RESPONSES
> >
> > Here would be error codes like 'param not found'
> >
> >
> >
> > ....// concrete data here based on java object type....
> >
> >
> >
> > So in essence I am looking to capture the response from an
> endpoint and wrap the data in my generic xml format. And I would
> like to centralize the generic stuff like error handling and have
> the ability to give the user a verbose message about the error they
> can easily consume (i.e. 'start date should be before end date'...)
> I am not sure if this would be trivial in jersey without having a
> lot of repetition in each of my methods. I am also supposed to
> support json,rss,atom so I am trying to keep all the 'plumbing' to a
> minimum.. I am not sure if this flies in the face of jax-rs or not?!?!
> >
> >
> > Also. I did not see this in the docs? Is it possible to specify
> return type in thu uri params. i.e. default to xml always but if you
> had...
> >
> > //myurl/service?format=atom
> >
> > have it auto detect the return type.
> >
> >
> > Thanks in advance.
> >
> > matt
> >