users@jersey.java.net

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

From: Pengfei Di <pengfei.di_at_match2blue.com>
Date: Fri, 11 Mar 2011 14:44:53 +0100

Hi, Martin

thank you so much for the explanation and the examples. However, it
doesn't work even when I put the 3 classes into my resource.
It seems that the HeaderOverrideFilter.fliter() method has never been
called. Should this Filter class be registered somewhere?

Best Regards
Pengfei

On 03/11/2011 11:25 AM, Martin Matula wrote:
> 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


-- 
Pengfei Di
Software Developer Backend
match2blue software development GmbH
Leutragraben 1
07743 Jena
Tel.: +49 3641 573 3474
Fax: +49 3641 573 3479
Email: pengfei.di_at_match2blue.com
Web: http://www.match2blue.com
Blog: http://blog.match2blue.com
Registergericht: Amtsgericht Jena
Registernummer: HRB 503726
Geschäftsführer: Stephanie Renda