users@jersey.java.net

[Jersey] Re: How to set http status when server returns a jaxb bean after processing post?

From: Martin Matula <martin.matula_at_oracle.com>
Date: Fri, 11 Mar 2011 11:25:34 +0100

Hi,
There is no standard easy way to do it. Status code 200 is hard-coded in
the dispatcher for all responses from methods returning an entity.
You should return the Response (and maybe have a separate method for
returning the jaxb bean).
Anyway, if you really need this, one (a bit hacky) way to achieve it is
using a ContainerResponseFilter and a custom Injectable.
Here is some code to give you an idea:

// injectable object you can use to pass info between your resource and
the filter
public class HeaderOverride {
     private final ThreadLocal<URI> location = new ThreadLocal<URI>();

     public void created(URI location) {
         this.location.set(location);
     }

     public URI fetchLocation() {
         URI result = location.get();
         location.set(null);
         return result;
     }
}

// injectable provider - this tells jersey how to inject HeaderOverride
object
@Provider
public class HeaderOverrideInjectableProvider extends
SingletonTypeInjectableProvider<Context, HeaderOverride> {
     public HeaderOverrideInjectableProvider() {
         super(HeaderOverride.class, new HeaderOverride());
     }
}

// filter that takes care of overriding the response code to 201 if
location set in HeaderOverride
// you have to register this filter in your JAX-RS app as a response filter
public class HeaderOverrideFilter implements ContainerResponseFilter {
     @Context HeaderOverride ho;

     @Override
     public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {
         URI location = ho.fetchLocation();
         if (location != null) {
             response.setStatus(201);
             response.getHttpHeaders().add(HttpHeaders.LOCATION,
location.toString());
         }
         return response;
     }
}


After adding the above classes to your app, you can override the
response code in your resource method as follows:
     // inject UriInfo and HeaderOverride to your resource class
     @Context UriInfo uriInfo;
     @Context HeaderOverride ho;

     @PUT
     public Bean put() {
         // business logic here
         ....
         // let's say you have a boolean named "created" which indicates
a new Bean had to be created
         if (created && ho != null) {
             // set location in the HeaderOverride to the request URI
(i.e. URI of this resource)
             ho.created(uriInfo.getRequestUri());
         }
         return "Hello world!";
     }

This way the method should still work if called outside of a request
scope (via some internal API or through some other means) and will do
the right thing if called through REST API. Hope this helps.
Martin

On 11.3.2011 8:43, pengfei.di_at_match2blue.com wrote:
> Hello Group,
>
> I am learning Jersey and encounter a problem: how can I modify the
> status in HttpHeader when the server returns a jaxb bean after
> processing a post request? The status is OK(200), but I think it would
> be better with CREATED(201).
>
> I found some suggestions from the Internet, which use Response as the
> return type and set the status directly in the Response. However I
> prefer to using jaxb bean as the return type for clean API and
> documentation.
>
>
> Thanks a lot in advance.
>
> Regards
> Pengfei