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 16:09:08 +0100

Yes, it needs to be registered as a ContainerResponseFilter. This
javadoc page discusses how to register filters:
http://jersey.java.net/nonav/apidocs/1.5/jersey/com/sun/jersey/api/container/filter/package-summary.html?is-external=true
Martin

On 11.3.2011 14:44, Pengfei Di wrote:
> 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
>
>