You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Voß,
Marko <Ma...@fiz-Karlsruhe.de> on 2012/03/26 17:04:41 UTC
Manipulating response header without returning
javax.ws.rs.core.Response
Hello,
we have an issue, where we cannot return the javax.ws.rs.core.Response
type in our method signatures of our JAX-RS interfaces. Example:
@Path("/foo")
public interface Foo {
@Path("/{id}")
...
JaxbFooObj retrieveFoo(@PathParam("id") String id) {
return logic.retrieve(id);
}
}
JaxbFooObj is a class generated by the JAXB maven-plugin, generated from
a schema file. The data of JaxbFooObj may be stored into a database. The
timestamp when this data has been stored or changed should become the
'Last-Modified' HTTP header value according to RFC 2822 or RFC 5322.
Returning javax.ws.rs.core.Response is no option because we need the
WADL-generator to use the return type to add the element type to the
representation element. Example:
<representation mediaType="text/xml" element="prefix1:foo"/>
I tried to solve this by writing a CXF interceptor:
public class CustomOutInterceptor extends
AbstractOutDatabindingInterceptor {
public CustomOutInterceptor() {
super(Phase.POST_LOGICAL);
}
public void handleMessage(Message message) {
Map<String, List<String>> headers = (Map<String,
List<String>>)message.get(Message.PROTOCOL_HEADERS);
if (headers == null) {
headers = new TreeMap<String,
List<String>>(String.CASE_INSENSITIVE_ORDER);
message.put(Message.PROTOCOL_HEADERS, headers);
}
List contents = message.getContent(List.class);
if (contents != null) {
for (int i=0; i<contents.size(); i++) {
if (contents.get(i) instanceof MetaObject) {
MetaObject meta = (MetaObject)contents.get(i);
contents.set(i, meta.getObj());
List<String> foo = new ArrayList<String>();
foo.add(meta.getLMD().toString());
headers.put("Last-Modified", foo);
return;
}
}
}
}
}
The MetaObject contains the JaxbFooObj and the last modification date.
This works but again, the element type is missing the in the generated
WADL. So the result is the same as by simply returning
javax.ws.rs.core.Response.
Can anyone help on this issue please?
Thank you in advance and kind regards,
Marko
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB 101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
Re: Manipulating response header without returning javax.ws.rs.core.Response
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Marko
On 26/03/12 17:21, Voß, Marko wrote:
> Hello Sergey,
>
> Thank you for pointing out the ElementClass annotation. This should do the job.
>
> I solved this issue right after my post to the mailing list by using "@Context HttpServletResponse response" in the method signature but I think, this is an "ugly" approach, because of the same JAX-RS interfaces are reused on client-side and the HttpServletResponse should not be available there. Your solution however looks great!
>
>> Is JaxbFooObj instance of MetaObject and with the method returning JaxbFooObj ? If yes then having the above interceptor should not affect the WADL generation.
>
> JaxbFooObj was the generic type of MetaObject and the method was returning MetaObject<JaxbFooObj>. I guess the WADL generator will only look at the interface/class annotations. I forgot to mention this.
WADLGenerator may be ignoring the generic type, though I think it should
add those provided in List<JaxbFooObject>, I'll have a look
>
>> By the way, do you expect the timestamp property returned to the client?
>
> I expect the timestamp to appear in the HTTP response header for the client. I tested it using Firefox Live-HTTP headers and it works.
>
>
> Since we have to use the javax.ws.rs.core.Response return type, the clients, which are reusing these JAX-RS interfaces, will now get the javax.ws.rs.core.Response type instead of the real type. I kinda dislike this but I guess, there is no other way. It would be nice, if the javax.ws.rs.core.Response type would be generic.
>
It will be easier to work with Response in JAX-RS 2.0, I'm not sure
Response will be made generic though as there's still some 'tension' on
the api level as to whether get it shared between client & server
runtimes or not. CXF ResponseReader provider can be registered on the
client side and used to cast from response.getEntity() to the specific
type. I'll have to resolve your JIRA though as won't fix :-) as it's not
a CXF level issue
Cheers, Sergey
>
> Kind regards,
>
> Marko
>
> -----Original Message-----
> From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
> Sent: Monday, March 26, 2012 5:59 PM
> To: users@cxf.apache.org
> Subject: Re: Manipulating response header without returning javax.ws.rs.core.Response
>
> Hi Marko
> On 26/03/12 16:04, Voß, Marko wrote:
>> Hello,
>>
>> we have an issue, where we cannot return the javax.ws.rs.core.Response
>> type in our method signatures of our JAX-RS interfaces. Example:
>>
>> @Path("/foo")
>> public interface Foo {
>>
>> @Path("/{id}")
>> ...
>> JaxbFooObj retrieveFoo(@PathParam("id") String id) {
>> return logic.retrieve(id);
>> }
>> }
>>
>> JaxbFooObj is a class generated by the JAXB maven-plugin, generated
>> from a schema file. The data of JaxbFooObj may be stored into a
>> database. The timestamp when this data has been stored or changed
>> should become the 'Last-Modified' HTTP header value according to RFC 2822 or RFC 5322.
>> Returning javax.ws.rs.core.Response is no option because we need the
>> WADL-generator to use the return type to add the element type to the
>> representation element. Example:
>>
>> <representation mediaType="text/xml" element="prefix1:foo"/>
>>
> Adding a method-level ElementClass annotation
> (http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/ElementClass.java)
> to the method returning Response should do it...
>
>
>> I tried to solve this by writing a CXF interceptor:
>>
>> public class CustomOutInterceptor extends
>> AbstractOutDatabindingInterceptor {
>>
>> public CustomOutInterceptor() {
>> super(Phase.POST_LOGICAL);
>> }
>>
>> public void handleMessage(Message message) {
>> Map<String, List<String>> headers = (Map<String,
>> List<String>>)message.get(Message.PROTOCOL_HEADERS);
>> if (headers == null) {
>> headers = new TreeMap<String,
>> List<String>>(String.CASE_INSENSITIVE_ORDER);
>> message.put(Message.PROTOCOL_HEADERS, headers);
>> }
>> List contents = message.getContent(List.class);
>> if (contents != null) {
>> for (int i=0; i<contents.size(); i++) {
>> if (contents.get(i) instanceof MetaObject) {
>> MetaObject meta = (MetaObject)contents.get(i);
>> contents.set(i, meta.getObj());
>>
>> List<String> foo = new ArrayList<String>();
>> foo.add(meta.getLMD().toString());
>> headers.put("Last-Modified", foo);
>> return;
>> }
>> }
>> }
>> }
>> }
>>
>> The MetaObject contains the JaxbFooObj and the last modification date.
>> This works but again, the element type is missing the in the generated
>> WADL. So the result is the same as by simply returning
>> javax.ws.rs.core.Response.
>>
>
> Is JaxbFooObj instance of MetaObject and with the method returning JaxbFooObj ? If yes then having the above interceptor should not affect the WADL generation.
> You should also be able to se ResponseHandler filter and override the Response there by copying the original Response and adding the required header. By the way, do you expect the timestamp property returned to the client ? If no then it can be stripped off with the transform feature
>
> Cheers, Sergey
>
>>
>> Can anyone help on this issue please?
>>
>>
>> Thank you in advance and kind regards,
>>
>> Marko
>>
>>
>> -------------------------------------------------------
>>
>> Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische Information mbH.
>> Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB 101892.
>> Geschäftsführerin: Sabine Brünger-Weilandt.
>> Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
>>
>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com
>
>
> -------------------------------------------------------
>
> Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische Information mbH.
> Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB 101892.
> Geschäftsführerin: Sabine Brünger-Weilandt.
> Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
>
>
RE: Manipulating response header without returning
javax.ws.rs.core.Response
Posted by Voß,
Marko <Ma...@fiz-Karlsruhe.de>.
Hello Sergey,
Thank you for pointing out the ElementClass annotation. This should do the job.
I solved this issue right after my post to the mailing list by using "@Context HttpServletResponse response" in the method signature but I think, this is an "ugly" approach, because of the same JAX-RS interfaces are reused on client-side and the HttpServletResponse should not be available there. Your solution however looks great!
> Is JaxbFooObj instance of MetaObject and with the method returning JaxbFooObj ? If yes then having the above interceptor should not affect the WADL generation.
JaxbFooObj was the generic type of MetaObject and the method was returning MetaObject<JaxbFooObj>. I guess the WADL generator will only look at the interface/class annotations. I forgot to mention this.
> By the way, do you expect the timestamp property returned to the client?
I expect the timestamp to appear in the HTTP response header for the client. I tested it using Firefox Live-HTTP headers and it works.
Since we have to use the javax.ws.rs.core.Response return type, the clients, which are reusing these JAX-RS interfaces, will now get the javax.ws.rs.core.Response type instead of the real type. I kinda dislike this but I guess, there is no other way. It would be nice, if the javax.ws.rs.core.Response type would be generic.
Kind regards,
Marko
-----Original Message-----
From: Sergey Beryozkin [mailto:sberyozkin@gmail.com]
Sent: Monday, March 26, 2012 5:59 PM
To: users@cxf.apache.org
Subject: Re: Manipulating response header without returning javax.ws.rs.core.Response
Hi Marko
On 26/03/12 16:04, Voß, Marko wrote:
> Hello,
>
> we have an issue, where we cannot return the javax.ws.rs.core.Response
> type in our method signatures of our JAX-RS interfaces. Example:
>
> @Path("/foo")
> public interface Foo {
>
> @Path("/{id}")
> ...
> JaxbFooObj retrieveFoo(@PathParam("id") String id) {
> return logic.retrieve(id);
> }
> }
>
> JaxbFooObj is a class generated by the JAXB maven-plugin, generated
> from a schema file. The data of JaxbFooObj may be stored into a
> database. The timestamp when this data has been stored or changed
> should become the 'Last-Modified' HTTP header value according to RFC 2822 or RFC 5322.
> Returning javax.ws.rs.core.Response is no option because we need the
> WADL-generator to use the return type to add the element type to the
> representation element. Example:
>
> <representation mediaType="text/xml" element="prefix1:foo"/>
>
Adding a method-level ElementClass annotation
(http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/ElementClass.java)
to the method returning Response should do it...
> I tried to solve this by writing a CXF interceptor:
>
> public class CustomOutInterceptor extends
> AbstractOutDatabindingInterceptor {
>
> public CustomOutInterceptor() {
> super(Phase.POST_LOGICAL);
> }
>
> public void handleMessage(Message message) {
> Map<String, List<String>> headers = (Map<String,
> List<String>>)message.get(Message.PROTOCOL_HEADERS);
> if (headers == null) {
> headers = new TreeMap<String,
> List<String>>(String.CASE_INSENSITIVE_ORDER);
> message.put(Message.PROTOCOL_HEADERS, headers);
> }
> List contents = message.getContent(List.class);
> if (contents != null) {
> for (int i=0; i<contents.size(); i++) {
> if (contents.get(i) instanceof MetaObject) {
> MetaObject meta = (MetaObject)contents.get(i);
> contents.set(i, meta.getObj());
>
> List<String> foo = new ArrayList<String>();
> foo.add(meta.getLMD().toString());
> headers.put("Last-Modified", foo);
> return;
> }
> }
> }
> }
> }
>
> The MetaObject contains the JaxbFooObj and the last modification date.
> This works but again, the element type is missing the in the generated
> WADL. So the result is the same as by simply returning
> javax.ws.rs.core.Response.
>
Is JaxbFooObj instance of MetaObject and with the method returning JaxbFooObj ? If yes then having the above interceptor should not affect the WADL generation.
You should also be able to se ResponseHandler filter and override the Response there by copying the original Response and adding the required header. By the way, do you expect the timestamp property returned to the client ? If no then it can be stripped off with the transform feature
Cheers, Sergey
>
> Can anyone help on this issue please?
>
>
> Thank you in advance and kind regards,
>
> Marko
>
>
> -------------------------------------------------------
>
> Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische Information mbH.
> Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB 101892.
> Geschäftsführerin: Sabine Brünger-Weilandt.
> Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
-------------------------------------------------------
Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische Information mbH.
Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB 101892.
Geschäftsführerin: Sabine Brünger-Weilandt.
Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
Re: Manipulating response header without returning javax.ws.rs.core.Response
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Marko
On 26/03/12 16:04, Voß, Marko wrote:
> Hello,
>
> we have an issue, where we cannot return the javax.ws.rs.core.Response
> type in our method signatures of our JAX-RS interfaces. Example:
>
> @Path("/foo")
> public interface Foo {
>
> @Path("/{id}")
> ...
> JaxbFooObj retrieveFoo(@PathParam("id") String id) {
> return logic.retrieve(id);
> }
> }
>
> JaxbFooObj is a class generated by the JAXB maven-plugin, generated from
> a schema file. The data of JaxbFooObj may be stored into a database. The
> timestamp when this data has been stored or changed should become the
> 'Last-Modified' HTTP header value according to RFC 2822 or RFC 5322.
> Returning javax.ws.rs.core.Response is no option because we need the
> WADL-generator to use the return type to add the element type to the
> representation element. Example:
>
> <representation mediaType="text/xml" element="prefix1:foo"/>
>
Adding a method-level ElementClass annotation
(http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/model/wadl/ElementClass.java)
to the method returning Response should do it...
> I tried to solve this by writing a CXF interceptor:
>
> public class CustomOutInterceptor extends
> AbstractOutDatabindingInterceptor {
>
> public CustomOutInterceptor() {
> super(Phase.POST_LOGICAL);
> }
>
> public void handleMessage(Message message) {
> Map<String, List<String>> headers = (Map<String,
> List<String>>)message.get(Message.PROTOCOL_HEADERS);
> if (headers == null) {
> headers = new TreeMap<String,
> List<String>>(String.CASE_INSENSITIVE_ORDER);
> message.put(Message.PROTOCOL_HEADERS, headers);
> }
> List contents = message.getContent(List.class);
> if (contents != null) {
> for (int i=0; i<contents.size(); i++) {
> if (contents.get(i) instanceof MetaObject) {
> MetaObject meta = (MetaObject)contents.get(i);
> contents.set(i, meta.getObj());
>
> List<String> foo = new ArrayList<String>();
> foo.add(meta.getLMD().toString());
> headers.put("Last-Modified", foo);
> return;
> }
> }
> }
> }
> }
>
> The MetaObject contains the JaxbFooObj and the last modification date.
> This works but again, the element type is missing the in the generated
> WADL. So the result is the same as by simply returning
> javax.ws.rs.core.Response.
>
Is JaxbFooObj instance of MetaObject and with the method returning
JaxbFooObj ? If yes then having the above interceptor should not affect
the WADL generation.
You should also be able to se ResponseHandler filter and override the
Response there by copying the original Response and adding the required
header. By the way, do you expect the timestamp property returned to the
client ? If no then it can be stripped off with the transform feature
Cheers, Sergey
>
> Can anyone help on this issue please?
>
>
> Thank you in advance and kind regards,
>
> Marko
>
>
> -------------------------------------------------------
>
> Fachinformationszentrum Karlsruhe, Gesellschaft für wissenschaftlich-technische Information mbH.
> Sitz der Gesellschaft: Eggenstein-Leopoldshafen, Amtsgericht Mannheim HRB 101892.
> Geschäftsführerin: Sabine Brünger-Weilandt.
> Vorsitzender des Aufsichtsrats: MinDirig Dr. Thomas Greiner.
>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com