Re: Questions about cxfrs
For those who may be interested, see the attached files to https://issues.apache.org/jira/browse/CAMEL-7147 (blueprint.xml, jaxrs-beans.xml), the route works nicely with CXF 2.7.7 with minor modifications, which won't be needed with the newer CXF versions Sergey On 22/01/14 22:13, David wrote: I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON provider instead of JacksonJsonProvider, and that results in an exception being thrown, telling me that no message body reader was found for my class. I'm using the same test case that's attached to the JIRA, just with a different JSON provider, and adding @XmlRootElement(name="container") to the domain class. On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin wrote: Hi, sure, I only referenced Jettison as a possible alternative. I think Jackson is picked up, Jettison only works, as you mentioned, with JAXB sending the write events to it, and as I understand you've no XMLRootElement/etc added to the data beans Sergey On 21/01/14 21:14, David wrote: Comments in-line. On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin wrote: Hi Please see comments below, On 21/01/14 17:01, David wrote: I think this is more of a Camel question than a CXF question, but let me know if that's not the case (would it have been bad form to cross-post this to cxf-user?). I have questions regarding use of Jackson with CXF, as well as how to get CXFRS not to wrap the root value of a JSON payload. I am trying to use Camel and CXF as part of a service orchestration using JSON over REST. My biggest question is how to configure cxfrs to use Jackson for all JSON marshal/unmarshal operations. So far, I've configured a cxf:rsServer and added a cxf:providers element with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider bean. I've also added the following to my route, although I haven't found anywhere to reference it yet: I'm basically exposing the configured cxf:rsServer service as an external entry-point: http://localhost:8182"; serviceClass="org.my.Service" loggingFeatureEnabled="true"> I'm then using a couple cxfrs producer endpoints to invoke external REST/JSON services implemented using RESTEasy: POST /service1/operation1 application/json http://localhost:8080?exchangePattern=InOut"/> POST /service2/operation2 application/json http://localhost:8080?exchangePattern=InOut"/> The idea is that each of those services will modify the payload, and the resulting object will be passed back to the caller. The services themselves are pretty standard. Class annotated with @Path, along with a single method annotated with @POST, @Consumes and @Produces (both types are set to MediaType.APPLICATION_JSON). The methods expect and return a single container class with id and a couple string values. When I call my service, however, an exception is thrown by the code that's attempting to call the cxfrs producer endpoint, saying there's no message body writer for my container class and applicaiton/json. At one point I had it working (not sure what was different back then) and I was running into issues where the CXF client code was wrapping the JSON payload (I.e. {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I got around it by registering a custom ContextResolver for the RESTEasy services that sets the WRAP_ROOT_VALUE feature on the Jackson object mapper, and adding a @JsonRootName annotation to my container class, but would prefer to solve the problem by telling the CXFRS client not to wrap the root value. From looking at http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see that both rsServer and rsClient have a "features" element that I think might allow me to do this, .but I can't find any documentation or examples for using it. I hope the above made sense, and thanks in advance for your help. The client-side wrapper is added by the active JSON provider which is Jackson in this case. I might be doing something wrong, but that doesn't seem to be the case. It seems to be using Jackson for the service I'm exposing using cxf:rsServer. However, the cxfrs client endpoint (I.e. http://etc.../>) seems to still be using Jettison. I also tried configuring a cxf:rsClient to access one of my external services, but the paths from my configured cxf:rsServer bean keep getting appended to the end of my URL. Are the two beans tightly coupled somehow? I.e. http://localhost:8182"; serviceClass="my.Service1" loggingFeatureEnabled="true"> http://localhost:8080/service2/service2path"; serviceClass="my.Service2" loggingFeatureEnabled="true"> When my route attempts to invoke Service2, the URI is set to: http://localh
Re: Questions about cxfrs
Thanks for the suggestion, I'll look into it as a temporary workaround. On Thu, Jan 23, 2014 at 5:17 AM, Sergey Beryozkin wrote: > Hi, > > I haven't had a chance to look into it yet, will do asap > What about this alternative (assuming you'd like to do it the JAX-RS way): > Create a CXF jaxrs:server entry endpoint with the address like > "camel://myservice", and link to it from Camel Servlet. This endpoint > service implementation will be a regular JAX-RS server (there will be no > null returns, etc) which will do a couple of HTTP invocations using > whatever Http API is preferred, example, you can try CXF WebClient or proxy > support. > Not sure if it will fir the purpose, suggesting it as a possible > workaround. > > Sergey > > > On 22/01/14 22:13, David wrote: > >> I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON >> provider instead of JacksonJsonProvider, and that results in an exception >> being thrown, telling me that no message body reader was found for my >> class. I'm using the same test case that's attached to the JIRA, just with >> a different JSON provider, and adding @XmlRootElement(name="container") >> to >> the domain class. >> >> >> >> On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin > >wrote: >> >> Hi, sure, I only referenced Jettison as a possible alternative. >>> I think Jackson is picked up, Jettison only works, as you mentioned, with >>> JAXB sending the write events to it, and as I understand you've no >>> XMLRootElement/etc added to the data beans >>> >>> Sergey >>> >>> On 21/01/14 21:14, David wrote: >>> >>> Comments in-line. On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin < sberyoz...@gmail.com > wrote: > Hi > Please see comments below, > > On 21/01/14 17:01, David wrote: > > I think this is more of a Camel question than a CXF question, but > let me > >> know if that's not the case (would it have been bad form to cross-post >> this >> to cxf-user?). >> >> I have questions regarding use of Jackson with CXF, as well as how to >> get >> CXFRS not to wrap the root value of a JSON payload. >> >> I am trying to use Camel and CXF as part of a service orchestration >> using >> JSON over REST. My biggest question is how to configure cxfrs to use >> Jackson for all JSON marshal/unmarshal operations. >> >> So far, I've configured a cxf:rsServer and added a cxf:providers >> element >> with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider >> bean. >> I've also added the following to my route, although I haven't found >> anywhere to reference it yet: >> >> >> >> >> >> I'm basically exposing the configured cxf:rsServer service as an >> external >> entry-point: >> >> http://localhost:8182"; >> serviceClass="org.my.Service" >> loggingFeatureEnabled="true"> >> >> >> >> >> > class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" /> >> >> I'm then using a couple cxfrs producer endpoints to invoke external >> REST/JSON services implemented using RESTEasy: >> >> >>POST >> >> >>/service1/operation1 >> >> >>application/json >> >>http://localhost:8080?exchangePattern=InOut >> "/> >> >>POST >> >> >>/service2/operation2 >> >> >>application/json >> >>http://localhost:8080?exchangePattern=InOut >> "/> >> >> >> The idea is that each of those services will modify the payload, and >> the >> resulting object will be passed back to the caller. >> >> The services themselves are pretty standard. Class annotated with >> @Path, >> along with a single method annotated with @POST, @Consumes and >> @Produces >> (both types are set to MediaType.APPLICATION_JSON). The methods expect >> and >> return a single container class with id and a couple string values. >> >> When I call my service, however, an exception is thrown by the code >> that's >> attempting to call the cxfrs producer endpoint, saying there's no >> message >> body writer for my container class and applicaiton/json. At one point >> I >> had >> it working (not sure what was different back then) and I was running >> into >> issues where the CXF client code was wrapping the JSON payload (I.e. >> {"classname": {"id": 1, ...}}), which the RESTEasy services didn't >> like. I >> got around it by registering a custom ContextResolver for the RESTEasy >> services that sets the WRAP_ROOT_VALUE feat
Re: Questions about cxfrs
Hi, I haven't had a chance to look into it yet, will do asap What about this alternative (assuming you'd like to do it the JAX-RS way): Create a CXF jaxrs:server entry endpoint with the address like "camel://myservice", and link to it from Camel Servlet. This endpoint service implementation will be a regular JAX-RS server (there will be no null returns, etc) which will do a couple of HTTP invocations using whatever Http API is preferred, example, you can try CXF WebClient or proxy support. Not sure if it will fir the purpose, suggesting it as a possible workaround. Sergey On 22/01/14 22:13, David wrote: I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON provider instead of JacksonJsonProvider, and that results in an exception being thrown, telling me that no message body reader was found for my class. I'm using the same test case that's attached to the JIRA, just with a different JSON provider, and adding @XmlRootElement(name="container") to the domain class. On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin wrote: Hi, sure, I only referenced Jettison as a possible alternative. I think Jackson is picked up, Jettison only works, as you mentioned, with JAXB sending the write events to it, and as I understand you've no XMLRootElement/etc added to the data beans Sergey On 21/01/14 21:14, David wrote: Comments in-line. On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin wrote: Hi Please see comments below, On 21/01/14 17:01, David wrote: I think this is more of a Camel question than a CXF question, but let me know if that's not the case (would it have been bad form to cross-post this to cxf-user?). I have questions regarding use of Jackson with CXF, as well as how to get CXFRS not to wrap the root value of a JSON payload. I am trying to use Camel and CXF as part of a service orchestration using JSON over REST. My biggest question is how to configure cxfrs to use Jackson for all JSON marshal/unmarshal operations. So far, I've configured a cxf:rsServer and added a cxf:providers element with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider bean. I've also added the following to my route, although I haven't found anywhere to reference it yet: I'm basically exposing the configured cxf:rsServer service as an external entry-point: http://localhost:8182"; serviceClass="org.my.Service" loggingFeatureEnabled="true"> I'm then using a couple cxfrs producer endpoints to invoke external REST/JSON services implemented using RESTEasy: POST /service1/operation1 application/json http://localhost:8080?exchangePattern=InOut"/> POST /service2/operation2 application/json http://localhost:8080?exchangePattern=InOut"/> The idea is that each of those services will modify the payload, and the resulting object will be passed back to the caller. The services themselves are pretty standard. Class annotated with @Path, along with a single method annotated with @POST, @Consumes and @Produces (both types are set to MediaType.APPLICATION_JSON). The methods expect and return a single container class with id and a couple string values. When I call my service, however, an exception is thrown by the code that's attempting to call the cxfrs producer endpoint, saying there's no message body writer for my container class and applicaiton/json. At one point I had it working (not sure what was different back then) and I was running into issues where the CXF client code was wrapping the JSON payload (I.e. {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I got around it by registering a custom ContextResolver for the RESTEasy services that sets the WRAP_ROOT_VALUE feature on the Jackson object mapper, and adding a @JsonRootName annotation to my container class, but would prefer to solve the problem by telling the CXFRS client not to wrap the root value. From looking at http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see that both rsServer and rsClient have a "features" element that I think might allow me to do this, .but I can't find any documentation or examples for using it. I hope the above made sense, and thanks in advance for your help. The client-side wrapper is added by the active JSON provider which is Jackson in this case. I might be doing something wrong, but that doesn't seem to be the case. It seems to be using Jackson for the service I'm exposing using cxf:rsServer. However, the cxfrs client endpoint (I.e. http://etc.../>) seems to still be using Jettison. I also tried configuring a cxf:rsClient to access one of my external services, but the paths from my configured cxf:rsServer bean keep getting appended to the end of my U
Re: Questions about cxfrs
I tried using org.apache.cxf.jaxrs.provider.json.JSONProvider as the JSON provider instead of JacksonJsonProvider, and that results in an exception being thrown, telling me that no message body reader was found for my class. I'm using the same test case that's attached to the JIRA, just with a different JSON provider, and adding @XmlRootElement(name="container") to the domain class. On Wed, Jan 22, 2014 at 5:23 AM, Sergey Beryozkin wrote: > Hi, sure, I only referenced Jettison as a possible alternative. > I think Jackson is picked up, Jettison only works, as you mentioned, with > JAXB sending the write events to it, and as I understand you've no > XMLRootElement/etc added to the data beans > > Sergey > > On 21/01/14 21:14, David wrote: > >> Comments in-line. >> >> >> On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin > >wrote: >> >> Hi >>> Please see comments below, >>> >>> On 21/01/14 17:01, David wrote: >>> >>> I think this is more of a Camel question than a CXF question, but let me know if that's not the case (would it have been bad form to cross-post this to cxf-user?). I have questions regarding use of Jackson with CXF, as well as how to get CXFRS not to wrap the root value of a JSON payload. I am trying to use Camel and CXF as part of a service orchestration using JSON over REST. My biggest question is how to configure cxfrs to use Jackson for all JSON marshal/unmarshal operations. So far, I've configured a cxf:rsServer and added a cxf:providers element with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider bean. I've also added the following to my route, although I haven't found anywhere to reference it yet: I'm basically exposing the configured cxf:rsServer service as an external entry-point: http://localhost:8182"; serviceClass="org.my.Service" loggingFeatureEnabled="true"> >>> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" /> I'm then using a couple cxfrs producer endpoints to invoke external REST/JSON services implemented using RESTEasy: POST /service1/operation1 application/json http://localhost:8080?exchangePattern=InOut"/> POST /service2/operation2 application/json http://localhost:8080?exchangePattern=InOut"/> The idea is that each of those services will modify the payload, and the resulting object will be passed back to the caller. The services themselves are pretty standard. Class annotated with @Path, along with a single method annotated with @POST, @Consumes and @Produces (both types are set to MediaType.APPLICATION_JSON). The methods expect and return a single container class with id and a couple string values. When I call my service, however, an exception is thrown by the code that's attempting to call the cxfrs producer endpoint, saying there's no message body writer for my container class and applicaiton/json. At one point I had it working (not sure what was different back then) and I was running into issues where the CXF client code was wrapping the JSON payload (I.e. {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I got around it by registering a custom ContextResolver for the RESTEasy services that sets the WRAP_ROOT_VALUE feature on the Jackson object mapper, and adding a @JsonRootName annotation to my container class, but would prefer to solve the problem by telling the CXFRS client not to wrap the root value. From looking at http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see that both rsServer and rsClient have a "features" element that I think might allow me to do this, .but I can't find any documentation or examples for using it. I hope the above made sense, and thanks in advance for your help. The client-side wrapper is added by the active JSON provider which is >>> Jackson in this case. >>> >> >> >> I might be doing something wrong, but that doesn't seem to be the case. It >> seems to be using Jackson for the service I'm exposing using cxf:rsServer. >> However, the cxfrs client endpoint (I.e. http://etc.../>) >> seems to still be using Jettison. I also tried configuring a cxf:rsClient >> to access one of my external services, but the paths from my configured >> cxf:rsServer bean keep getting appended to the end of my URL. Are the two >> beans tightly coupled someh
Re: Questions about cxfrs
See https://issues.apache.org/jira/browse/CAMEL-7147 On Wed, Jan 22, 2014 at 10:58 AM, Sergey Beryozkin wrote: > Hi, > > On 22/01/14 14:20, David wrote: > >> I can create a test project. How would I get it to you, email to the list >> as attachment? Or would it be better to open a JIRA, maybe? >> >> Can you please open a JIRA and attach a test project there > Many thanks > Sergey > >> >> >> On Wed, Jan 22, 2014 at 5:19 AM, Sergey Beryozkin > >wrote: >> >> The stack trace suggests that JacksonJsonProvider did have a thread local >>> context representing JAX-RS Providers injected into it at the >>> registration >>> time but at the invocation time no thread-local entry has been added to >>> it >>> and hence NPE. >>> I have a lot of tests in CXF where client-side providers have the >>> contexts >>> injected, so I think it is somehow related to the way the client >>> invocation >>> is managed by cxfrs. >>> I'm just curious how to reproduce it. Is there any chance that you can >>> create a basic test project ? I will try to reproduce it on my own too >>> >>> Sergey >>> >>> >>> >>> On 22/01/14 03:51, David wrote: >>> >>> On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang >>> > wrote: > On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) > wrote: > > When my route attempts to invoke Service2, the URI is set to: >> >>> >>> http://localhost:8080/service2/service2path/service1/service1path, >> where >> service1/service1path is configured in my.Service1. I'm also >> not sure why >> I'm providing a serviceClass for rsClient. I thought maybe it >> was going to >> instantiate my service, but that doesn't seem to be the case. >> >> >> If you routing the response of first service to second service, you > may > need to clean up the CamelHttpPath message header. > > > Thanks, that was very helpful, but I'm not quite there yet. Shouldn't > this header be cleared when I set inheritHeaders to false? I had made both the first and second service have the same http path in order to trick the camel route into working, and initially removing the header had the desired effect -- I.e.I got a 404 response because the path for the second service had been truncated. However, when I changed the entry-point service back to its original path, I got an NPE (at org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver( ThreadLocalProviders.java:50)). I fixed that by instead setting the CamelHttpPath to the path for the next service, which worked. Next, I added in the third service, by wiring a second rsClient for it and duplicating the setHeader and cxfrs producer endpoint in the camel route. This mostly works, but not quite. When the response comes back from service2, my object is populated as expected. However, by the time the call to service3 happens, all variables in the object have been set to 0 for the int and null for the strings. Service3 is then called with this empty object and returns. Finally, I again get the same NPE from Service1. I tried resetting the CamelHttpPath to the initial value, but that didn't fix the NPE. Removing Service3 also doesn't fix the NPE during the Service1 response, and the variables in the object are also still reset to 0/null. Here's my route, as it stands now: /service2/service2path >>> uri="cxfrs:bean:Service2"/> /service3/service3path The same NPE I'm seeing was also seen here, apparently: http://mail-archives.apache.org/mod_mbox/cxf-users/201311. mbox/%3c52987699.6040...@gmail.com%3E Here's a more complete stacktrace from my logs: -- 22:38:54,309 | INFO | tp2013341004-662 | response | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut, BodyType: mycompany.MyObject, Body: {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}] 22:38:54,311 | WARN | tp2013341004-662 | PhaseInterceptorChain | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for { http://myservice.mycompany.com/}Service1 has thrown exception, unwinding now javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor. handleWriteException(JAXRSOutInterceptor.java:396)[ 166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage( JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt- frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse( JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt- frontend-jaxrs
Re: Questions about cxfrs
Hi, On 22/01/14 14:20, David wrote: I can create a test project. How would I get it to you, email to the list as attachment? Or would it be better to open a JIRA, maybe? Can you please open a JIRA and attach a test project there Many thanks Sergey On Wed, Jan 22, 2014 at 5:19 AM, Sergey Beryozkin wrote: The stack trace suggests that JacksonJsonProvider did have a thread local context representing JAX-RS Providers injected into it at the registration time but at the invocation time no thread-local entry has been added to it and hence NPE. I have a lot of tests in CXF where client-side providers have the contexts injected, so I think it is somehow related to the way the client invocation is managed by cxfrs. I'm just curious how to reproduce it. Is there any chance that you can create a basic test project ? I will try to reproduce it on my own too Sergey On 22/01/14 03:51, David wrote: On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang wrote: On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote: When my route attempts to invoke Service2, the URI is set to: http://localhost:8080/service2/service2path/service1/service1path, where service1/service1path is configured in my.Service1. I'm also not sure why I'm providing a serviceClass for rsClient. I thought maybe it was going to instantiate my service, but that doesn't seem to be the case. If you routing the response of first service to second service, you may need to clean up the CamelHttpPath message header. Thanks, that was very helpful, but I'm not quite there yet. Shouldn't this header be cleared when I set inheritHeaders to false? I had made both the first and second service have the same http path in order to trick the camel route into working, and initially removing the header had the desired effect -- I.e.I got a 404 response because the path for the second service had been truncated. However, when I changed the entry-point service back to its original path, I got an NPE (at org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver( ThreadLocalProviders.java:50)). I fixed that by instead setting the CamelHttpPath to the path for the next service, which worked. Next, I added in the third service, by wiring a second rsClient for it and duplicating the setHeader and cxfrs producer endpoint in the camel route. This mostly works, but not quite. When the response comes back from service2, my object is populated as expected. However, by the time the call to service3 happens, all variables in the object have been set to 0 for the int and null for the strings. Service3 is then called with this empty object and returns. Finally, I again get the same NPE from Service1. I tried resetting the CamelHttpPath to the initial value, but that didn't fix the NPE. Removing Service3 also doesn't fix the NPE during the Service1 response, and the variables in the object are also still reset to 0/null. Here's my route, as it stands now: /service2/service2path /service3/service3path The same NPE I'm seeing was also seen here, apparently: http://mail-archives.apache.org/mod_mbox/cxf-users/201311. mbox/%3c52987699.6040...@gmail.com%3E Here's a more complete stacktrace from my logs: -- 22:38:54,309 | INFO | tp2013341004-662 | response | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut, BodyType: mycompany.MyObject, Body: {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}] 22:38:54,311 | WARN | tp2013341004-662 | PhaseInterceptorChain | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for { http://myservice.mycompany.com/}Service1 has thrown exception, unwinding now javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor. handleWriteException(JAXRSOutInterceptor.java:396)[ 166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage( JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt- frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse( JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt- frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage( JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt- frontend-jaxrs:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept( PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage( OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept( PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.resume( PhaseInterceptorChain.java:242)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.transport.ChainInitiationObserver.onMessage( ChainInitiationObserver.java:78)[150:org.apac
Re: Questions about cxfrs
I can create a test project. How would I get it to you, email to the list as attachment? Or would it be better to open a JIRA, maybe? On Wed, Jan 22, 2014 at 5:19 AM, Sergey Beryozkin wrote: > The stack trace suggests that JacksonJsonProvider did have a thread local > context representing JAX-RS Providers injected into it at the registration > time but at the invocation time no thread-local entry has been added to it > and hence NPE. > I have a lot of tests in CXF where client-side providers have the contexts > injected, so I think it is somehow related to the way the client invocation > is managed by cxfrs. > I'm just curious how to reproduce it. Is there any chance that you can > create a basic test project ? I will try to reproduce it on my own too > > Sergey > > > > On 22/01/14 03:51, David wrote: > >> On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang > >wrote: >> >> >>> On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote: >>> When my route attempts to invoke Service2, the URI is set to: > http://localhost:8080/service2/service2path/service1/service1path, where service1/service1path is configured in my.Service1. I'm also not sure why I'm providing a serviceClass for rsClient. I thought maybe it was going to instantiate my service, but that doesn't seem to be the case. >>> If you routing the response of first service to second service, you may >>> need to clean up the CamelHttpPath message header. >>> >>> >>> Thanks, that was very helpful, but I'm not quite there yet. Shouldn't >> this >> header be cleared when I set inheritHeaders to false? >> >> I had made both the first and second service have the same http path in >> order to trick the camel route into working, and initially removing the >> header had the desired effect -- I.e.I got a 404 response because the path >> for the second service had been truncated. However, when I changed the >> entry-point service back to its original path, I got an NPE (at >> org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver( >> ThreadLocalProviders.java:50)). >> I fixed that by instead setting the CamelHttpPath to the path for the next >> service, which worked. >> >> Next, I added in the third service, by wiring a second rsClient for it and >> duplicating the setHeader and cxfrs producer endpoint in the camel route. >> This mostly works, but not quite. When the response comes back from >> service2, my object is populated as expected. However, by the time the >> call >> to service3 happens, all variables in the object have been set to 0 for >> the >> int and null for the strings. Service3 is then called with this empty >> object and returns. Finally, I again get the same NPE from Service1. I >> tried resetting the CamelHttpPath to the initial value, but that didn't >> fix >> the NPE. Removing Service3 also doesn't fix the NPE during the Service1 >> response, and the variables in the object are also still reset to 0/null. >> >> Here's my route, as it stands now: >> >> >> >> /service2/service2path > uri="cxfrs:bean:Service2"/> >> >> /service3/service3path >> >> >> >> The same NPE I'm seeing was also seen here, apparently: >> >> http://mail-archives.apache.org/mod_mbox/cxf-users/201311. >> mbox/%3c52987699.6040...@gmail.com%3E >> >> Here's a more complete stacktrace from my logs: >> >> -- >> 22:38:54,309 | INFO | tp2013341004-662 | response >> | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut, >> BodyType: mycompany.MyObject, Body: >> {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}] >> 22:38:54,311 | WARN | tp2013341004-662 | PhaseInterceptorChain >> | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for { >> http://myservice.mycompany.com/}Service1 has thrown exception, unwinding >> now >> javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor. >> handleWriteException(JAXRSOutInterceptor.java:396)[ >> 166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage( >> JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt- >> frontend-jaxrs:2.7.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse( >> JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt- >> frontend-jaxrs:2.7.0] >> at >> org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage( >> JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt- >> frontend-jaxrs:2.7.0] >> at >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept( >> PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] >> at >> org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage( >> OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0] >> at >> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept( >> PhaseInterceptorChain.java:272)[150:org.apache.cxf.
Re: Questions about cxfrs
Hi, sure, I only referenced Jettison as a possible alternative. I think Jackson is picked up, Jettison only works, as you mentioned, with JAXB sending the write events to it, and as I understand you've no XMLRootElement/etc added to the data beans Sergey On 21/01/14 21:14, David wrote: Comments in-line. On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin wrote: Hi Please see comments below, On 21/01/14 17:01, David wrote: I think this is more of a Camel question than a CXF question, but let me know if that's not the case (would it have been bad form to cross-post this to cxf-user?). I have questions regarding use of Jackson with CXF, as well as how to get CXFRS not to wrap the root value of a JSON payload. I am trying to use Camel and CXF as part of a service orchestration using JSON over REST. My biggest question is how to configure cxfrs to use Jackson for all JSON marshal/unmarshal operations. So far, I've configured a cxf:rsServer and added a cxf:providers element with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider bean. I've also added the following to my route, although I haven't found anywhere to reference it yet: I'm basically exposing the configured cxf:rsServer service as an external entry-point: http://localhost:8182"; serviceClass="org.my.Service" loggingFeatureEnabled="true"> I'm then using a couple cxfrs producer endpoints to invoke external REST/JSON services implemented using RESTEasy: POST /service1/operation1 application/json http://localhost:8080?exchangePattern=InOut"/> POST /service2/operation2 application/json http://localhost:8080?exchangePattern=InOut"/> The idea is that each of those services will modify the payload, and the resulting object will be passed back to the caller. The services themselves are pretty standard. Class annotated with @Path, along with a single method annotated with @POST, @Consumes and @Produces (both types are set to MediaType.APPLICATION_JSON). The methods expect and return a single container class with id and a couple string values. When I call my service, however, an exception is thrown by the code that's attempting to call the cxfrs producer endpoint, saying there's no message body writer for my container class and applicaiton/json. At one point I had it working (not sure what was different back then) and I was running into issues where the CXF client code was wrapping the JSON payload (I.e. {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I got around it by registering a custom ContextResolver for the RESTEasy services that sets the WRAP_ROOT_VALUE feature on the Jackson object mapper, and adding a @JsonRootName annotation to my container class, but would prefer to solve the problem by telling the CXFRS client not to wrap the root value. From looking at http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see that both rsServer and rsClient have a "features" element that I think might allow me to do this, .but I can't find any documentation or examples for using it. I hope the above made sense, and thanks in advance for your help. The client-side wrapper is added by the active JSON provider which is Jackson in this case. I might be doing something wrong, but that doesn't seem to be the case. It seems to be using Jackson for the service I'm exposing using cxf:rsServer. However, the cxfrs client endpoint (I.e. http://etc.../>) seems to still be using Jettison. I also tried configuring a cxf:rsClient to access one of my external services, but the paths from my configured cxf:rsServer bean keep getting appended to the end of my URL. Are the two beans tightly coupled somehow? I.e. http://localhost:8182"; serviceClass="my.Service1" loggingFeatureEnabled="true"> http://localhost:8080/service2/service2path"; serviceClass="my.Service2" loggingFeatureEnabled="true"> When my route attempts to invoke Service2, the URI is set to: http://localhost:8080/service2/service2path/service1/service1path, where service1/service1path is configured in my.Service1. I'm also not sure why I'm providing a serviceClass for rsClient. I thought maybe it was going to instantiate my service, but that doesn't seem to be the case. So one option is to configure org.codehaus.jackson.jaxrs.JacksonJsonProvider directly in Spring to drop a root element - that should be possible. Can you try it ? I was able to find an example for wiring a Jackson ObjectMapper bean and providing a reference to it to the JacksonJsonProvider bean, but I need to get my service client working before I can test it. By the way, how complex the actual sequence is ? The other alternative can be to use CXF JSONProvider (Jettison-based) - it is quite
Re: Questions about cxfrs
The stack trace suggests that JacksonJsonProvider did have a thread local context representing JAX-RS Providers injected into it at the registration time but at the invocation time no thread-local entry has been added to it and hence NPE. I have a lot of tests in CXF where client-side providers have the contexts injected, so I think it is somehow related to the way the client invocation is managed by cxfrs. I'm just curious how to reproduce it. Is there any chance that you can create a basic test project ? I will try to reproduce it on my own too Sergey On 22/01/14 03:51, David wrote: On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang wrote: On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote: When my route attempts to invoke Service2, the URI is set to: http://localhost:8080/service2/service2path/service1/service1path, where service1/service1path is configured in my.Service1. I'm also not sure why I'm providing a serviceClass for rsClient. I thought maybe it was going to instantiate my service, but that doesn't seem to be the case. If you routing the response of first service to second service, you may need to clean up the CamelHttpPath message header. Thanks, that was very helpful, but I'm not quite there yet. Shouldn't this header be cleared when I set inheritHeaders to false? I had made both the first and second service have the same http path in order to trick the camel route into working, and initially removing the header had the desired effect -- I.e.I got a 404 response because the path for the second service had been truncated. However, when I changed the entry-point service back to its original path, I got an NPE (at org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)). I fixed that by instead setting the CamelHttpPath to the path for the next service, which worked. Next, I added in the third service, by wiring a second rsClient for it and duplicating the setHeader and cxfrs producer endpoint in the camel route. This mostly works, but not quite. When the response comes back from service2, my object is populated as expected. However, by the time the call to service3 happens, all variables in the object have been set to 0 for the int and null for the strings. Service3 is then called with this empty object and returns. Finally, I again get the same NPE from Service1. I tried resetting the CamelHttpPath to the initial value, but that didn't fix the NPE. Removing Service3 also doesn't fix the NPE during the Service1 response, and the variables in the object are also still reset to 0/null. Here's my route, as it stands now: /service2/service2path /service3/service3path The same NPE I'm seeing was also seen here, apparently: http://mail-archives.apache.org/mod_mbox/cxf-users/201311.mbox/%3c52987699.6040...@gmail.com%3E Here's a more complete stacktrace from my logs: -- 22:38:54,309 | INFO | tp2013341004-662 | response | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut, BodyType: mycompany.MyObject, Body: {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}] 22:38:54,311 | WARN | tp2013341004-662 | PhaseInterceptorChain | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for { http://myservice.mycompany.com/}Service1 has thrown exception, unwinding now javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleWriteException(JAXRSOutInterceptor.java:396)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0] at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)[176:org.apache.cxf.cxf-rt-transports-http-jetty:
Re: Questions about cxfrs
On Tue, Jan 21, 2014 at 8:16 PM, Willem Jiang wrote: > > On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote: > > > When my route attempts to invoke Service2, the URI is set to: > > http://localhost:8080/service2/service2path/service1/service1path, > > where > > service1/service1path is configured in my.Service1. I'm also > > not sure why > > I'm providing a serviceClass for rsClient. I thought maybe it > > was going to > > instantiate my service, but that doesn't seem to be the case. > > > > If you routing the response of first service to second service, you may > need to clean up the CamelHttpPath message header. > > Thanks, that was very helpful, but I'm not quite there yet. Shouldn't this header be cleared when I set inheritHeaders to false? I had made both the first and second service have the same http path in order to trick the camel route into working, and initially removing the header had the desired effect -- I.e.I got a 404 response because the path for the second service had been truncated. However, when I changed the entry-point service back to its original path, I got an NPE (at org.apache.cxf.jaxrs.impl.tl.ThreadLocalProviders.getContextResolver(ThreadLocalProviders.java:50)). I fixed that by instead setting the CamelHttpPath to the path for the next service, which worked. Next, I added in the third service, by wiring a second rsClient for it and duplicating the setHeader and cxfrs producer endpoint in the camel route. This mostly works, but not quite. When the response comes back from service2, my object is populated as expected. However, by the time the call to service3 happens, all variables in the object have been set to 0 for the int and null for the strings. Service3 is then called with this empty object and returns. Finally, I again get the same NPE from Service1. I tried resetting the CamelHttpPath to the initial value, but that didn't fix the NPE. Removing Service3 also doesn't fix the NPE during the Service1 response, and the variables in the object are also still reset to 0/null. Here's my route, as it stands now: /service2/service2path /service3/service3path The same NPE I'm seeing was also seen here, apparently: http://mail-archives.apache.org/mod_mbox/cxf-users/201311.mbox/%3c52987699.6040...@gmail.com%3E Here's a more complete stacktrace from my logs: -- 22:38:54,309 | INFO | tp2013341004-662 | response | 134 - org.apache.camel.camel-core | Exchange[ExchangePattern: InOut, BodyType: mycompany.MyObject, Body: {"myobject":{"id":0,"value1":null,"value2":null,"value3":0}}] 22:38:54,311 | WARN | tp2013341004-662 | PhaseInterceptorChain | 150 - org.apache.cxf.cxf-api - 2.7.0 | Interceptor for { http://myservice.mycompany.com/}Service1 has thrown exception, unwinding now javax.ws.rs.InternalServerErrorException: java.lang.NullPointerException at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleWriteException(JAXRSOutInterceptor.java:396)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:305)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)[166:org.apache.cxf.cxf-rt-frontend-jaxrs:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)[150:org.apache.cxf.cxf-api:2.7.0] at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:355)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0] at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:319)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0] at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)[176:org.apache.cxf.cxf-rt-transports-http-jetty:2.7.0] at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1077)[93:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131] at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1013)[93:org.eclipse.jetty.aggregate.jetty-all-server:8.1.9.v20130131] at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)[93:org.eclipse.jetty.aggregat
Re: Questions about cxfrs
On January 22, 2014 at 5:14:40 AM, David (wakarima...@gmail.com) wrote: > > When my route attempts to invoke Service2, the URI is set to: > http://localhost:8080/service2/service2path/service1/service1path, > where > service1/service1path is configured in my.Service1. I'm also > not sure why > I'm providing a serviceClass for rsClient. I thought maybe it > was going to > instantiate my service, but that doesn't seem to be the case. > If you routing the response of first service to second service, you may need to clean up the CamelHttpPath message header. -- Willem Jiang Red Hat, Inc. Web: http://www.redhat.com Blog: http://willemjiang.blogspot.com(http://willemjiang.blogspot.com/) (English) http://jnn.iteye.com(http://jnn.javaeye.com/) (Chinese) Twitter: willemjiang Weibo: 姜宁willem
Re: Questions about cxfrs
Comments in-line. On Tue, Jan 21, 2014 at 12:34 PM, Sergey Beryozkin wrote: > Hi > Please see comments below, > > On 21/01/14 17:01, David wrote: > >> I think this is more of a Camel question than a CXF question, but let me >> know if that's not the case (would it have been bad form to cross-post >> this >> to cxf-user?). >> >> I have questions regarding use of Jackson with CXF, as well as how to get >> CXFRS not to wrap the root value of a JSON payload. >> >> I am trying to use Camel and CXF as part of a service orchestration using >> JSON over REST. My biggest question is how to configure cxfrs to use >> Jackson for all JSON marshal/unmarshal operations. >> >> So far, I've configured a cxf:rsServer and added a cxf:providers element >> with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider >> bean. >> I've also added the following to my route, although I haven't found >> anywhere to reference it yet: >> >> >> >> >> >> I'm basically exposing the configured cxf:rsServer service as an external >> entry-point: >> >> http://localhost:8182"; >> serviceClass="org.my.Service" >> loggingFeatureEnabled="true"> >> >> >> >> >> > class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" /> >> >> I'm then using a couple cxfrs producer endpoints to invoke external >> REST/JSON services implemented using RESTEasy: >> >> >> POST >> >> >> /service1/operation1 >> >> >> application/json >> >> http://localhost:8080?exchangePattern=InOut"/> >> >> POST >> >> >> /service2/operation2 >> >> >> application/json >> >> http://localhost:8080?exchangePattern=InOut"/> >> >> >> The idea is that each of those services will modify the payload, and the >> resulting object will be passed back to the caller. >> >> The services themselves are pretty standard. Class annotated with @Path, >> along with a single method annotated with @POST, @Consumes and @Produces >> (both types are set to MediaType.APPLICATION_JSON). The methods expect and >> return a single container class with id and a couple string values. >> >> When I call my service, however, an exception is thrown by the code that's >> attempting to call the cxfrs producer endpoint, saying there's no message >> body writer for my container class and applicaiton/json. At one point I >> had >> it working (not sure what was different back then) and I was running into >> issues where the CXF client code was wrapping the JSON payload (I.e. >> {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I >> got around it by registering a custom ContextResolver for the RESTEasy >> services that sets the WRAP_ROOT_VALUE feature on the Jackson object >> mapper, and adding a @JsonRootName annotation to my container class, but >> would prefer to solve the problem by telling the CXFRS client not to wrap >> the root value. From looking at >> http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see >> that both rsServer and rsClient have a "features" element that I think >> might allow me to do this, .but I can't find any documentation or examples >> for using it. >> >> I hope the above made sense, and thanks in advance for your help. >> >> The client-side wrapper is added by the active JSON provider which is > Jackson in this case. I might be doing something wrong, but that doesn't seem to be the case. It seems to be using Jackson for the service I'm exposing using cxf:rsServer. However, the cxfrs client endpoint (I.e. http://etc.../>) seems to still be using Jettison. I also tried configuring a cxf:rsClient to access one of my external services, but the paths from my configured cxf:rsServer bean keep getting appended to the end of my URL. Are the two beans tightly coupled somehow? I.e. http://localhost:8182"; serviceClass="my.Service1" loggingFeatureEnabled="true"> http://localhost:8080/service2/service2path"; serviceClass="my.Service2" loggingFeatureEnabled="true"> When my route attempts to invoke Service2, the URI is set to: http://localhost:8080/service2/service2path/service1/service1path, where service1/service1path is configured in my.Service1. I'm also not sure why I'm providing a serviceClass for rsClient. I thought maybe it was going to instantiate my service, but that doesn't seem to be the case. > So one option is to configure org.codehaus.jackson.jaxrs.JacksonJsonProvider > directly in Spring to drop a root element - that should be possible. Can > you try it ? > I was able to find an example for wiring a Jackson ObjectMapper bean and providing a reference to it to the JacksonJsonProvider bean, but I need to get my service client working before I can test it. > > By the way, how complex the actual sequence is ? The other alternative can > be to use CXF JSONProvider (Jettison-based) - it is q
Re: Questions about cxfrs
Hi Please see comments below, On 21/01/14 17:01, David wrote: I think this is more of a Camel question than a CXF question, but let me know if that's not the case (would it have been bad form to cross-post this to cxf-user?). I have questions regarding use of Jackson with CXF, as well as how to get CXFRS not to wrap the root value of a JSON payload. I am trying to use Camel and CXF as part of a service orchestration using JSON over REST. My biggest question is how to configure cxfrs to use Jackson for all JSON marshal/unmarshal operations. So far, I've configured a cxf:rsServer and added a cxf:providers element with a reference to a org.codehaus.jackson.jaxrs.JacksonJsonProvider bean. I've also added the following to my route, although I haven't found anywhere to reference it yet: I'm basically exposing the configured cxf:rsServer service as an external entry-point: http://localhost:8182"; serviceClass="org.my.Service" loggingFeatureEnabled="true"> I'm then using a couple cxfrs producer endpoints to invoke external REST/JSON services implemented using RESTEasy: POST /service1/operation1 application/json http://localhost:8080?exchangePattern=InOut"/> POST /service2/operation2 application/json http://localhost:8080?exchangePattern=InOut"/> The idea is that each of those services will modify the payload, and the resulting object will be passed back to the caller. The services themselves are pretty standard. Class annotated with @Path, along with a single method annotated with @POST, @Consumes and @Produces (both types are set to MediaType.APPLICATION_JSON). The methods expect and return a single container class with id and a couple string values. When I call my service, however, an exception is thrown by the code that's attempting to call the cxfrs producer endpoint, saying there's no message body writer for my container class and applicaiton/json. At one point I had it working (not sure what was different back then) and I was running into issues where the CXF client code was wrapping the JSON payload (I.e. {"classname": {"id": 1, ...}}), which the RESTEasy services didn't like. I got around it by registering a custom ContextResolver for the RESTEasy services that sets the WRAP_ROOT_VALUE feature on the Jackson object mapper, and adding a @JsonRootName annotation to my container class, but would prefer to solve the problem by telling the CXFRS client not to wrap the root value. From looking at http://camel.apache.org/schema/blueprint/cxf/camel-cxf-2.9.0.xsd, I see that both rsServer and rsClient have a "features" element that I think might allow me to do this, .but I can't find any documentation or examples for using it. I hope the above made sense, and thanks in advance for your help. The client-side wrapper is added by the active JSON provider which is Jackson in this case. So one option is to configure org.codehaus.jackson.jaxrs.JacksonJsonProvider directly in Spring to drop a root element - that should be possible. Can you try it ? By the way, how complex the actual sequence is ? The other alternative can be to use CXF JSONProvider (Jettison-based) - it is quite flexible in the way it can shape the sequence Sergey