You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "Liu, Jervis" <jl...@iona.com> on 2008/02/04 09:17:01 UTC

RE: Issues with JSON based Service and Jettison


> -----Original Message-----
> From: Vespa, Anthony J [mailto:ajvespa@cbs.com]
> Sent: 2008年1月18日 5:38
> To: cxf-user@incubator.apache.org
> Subject: RE: Issues with JSON based Service and Jettison
> 
> Jervis, I actually got it working end to end - once I added the namespace as a
> property in my jettison settings of my beans.xml - it works quite nicely and
> even deals with my wrapper/anytypes.
> 
> Out of curiousity, there have been some oblique mentions here and there of
> having the incoming JSON parsed out into mapped variables, eg I have a
> JSON object named message with message: { id:1, name=foo} and a web
> service that takes id and name as params and outputs JSON - it seems from
> your previous emails this is not possible?  That only the jettison system will
> work with one argumenet?  Is this true of jax-rs as well?
> 
[Liu, Jervis] Hi Tony, you've got this almost right. When a JSON object comes in, it is transferred to a XML document first, for example, "{"acme.Book":{"acme.name":"CXF in Action ","acme.id":"123 "}}" is transferred to an org.w3c.dom.Document of <Book><name>CXF in Action</name><id>123</id></Book>. Then the XML document will be parsed and mapped to request parameters of the target method following the JAX-WS spec. Whether or not the XML document of <Book><name>CXF in Action</name><id>123</id></Book> is mapped to a Book object or mapped to two separate parameters of id and name is depending on doc/lit bare style or doc/lit wrapped style. The one argument limitation does nothing with Jettison, it comes from the implementation of CXF HTTP binding. JAX-RS does not have this limitation, you can have multiple parameters for your resource method, for example, one parameter mapped from http header, one from URL path variable, one from Http body. Note the Http body can only be mapped to one parameter. This is defined by JSR-311 spec.

> Thanks again for your guidance  - it helped me a lot with the issues I was
> having.  Once I get things settled, I'll try to write up a workable example for
> inclusion.
> 
> -Tony
> 
> -----Original Message-----
> From: Liu, Jervis [mailto:jliu@iona.com]
> Sent: Wednesday, January 16, 2008 10:25 PM
> To: cxf-user@incubator.apache.org
> Subject: RE: Issues with JSON based Service and Jettison
> 
> You got 'Invalid URL/Verb combination. Verb: POST Path: /message'
> exception when the combination of "Verb: POST" and "Path: /message" did
> not find a method from your service. Not sure why though as your service
> looks alright. You may want to paste out the initialization information when
> your server is starting up, it normally says sth like below:
> 
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method getBook to resource /books/{id} and verb GET
> 2008-1-17 11:23:08 org.apache.cxf.endpoint.ServerImpl initDestination
> INFO: Setting the server's publish address to be
> http://localhost:9080/xmlwrapped
> 2008-1-17 11:23:08
> org.apache.cxf.service.factory.ReflectionServiceFactoryBean
> buildServiceFromClass
> INFO: Creating Service {http://book.acme.com}BookServiceService from
> class org.apache.cxf.customer.book.BookService
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method updateBook to resource /books/{id} and verb PUT
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method getBooks to resource /books and verb GET
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method getAnotherBook to resource /books/another/{id}
> and verb GET
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method addBook to resource /books and verb POST
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method getBook to resource /books/{id} and verb GET
> 2008-1-17 11:23:08 org.apache.cxf.binding.http.strategy.JRAStrategy map
> INFO: Mapping method deleteBook to resource /books/{id} and verb DELETE
> 2008-1-17 11:23:08 org.apache.cxf.endpoint.ServerImpl initDestination
> INFO: Setting the server's publish address to be http://localhost:9080/json
> 
> 
> > -----Original Message-----
> > From: Vespa, Anthony J [mailto:ajvespa@cbs.com]
> > Sent: 2008年1月17日 0:05
> > To: cxf-user@incubator.apache.org
> > Subject: RE: Issues with JSON based Service and Jettison
> >
> > So after some thought and tweaking I adjusted my JSON service, but I am
> > getting the 'Invalid URL/Verb combination. Verb: POST Path: /message'
> > exception.
> >
> > My service looks like this:
> >
> > @WebService(targetNamespace = "http://com.cbs.bos.ws.json")
> > public interface BoardService {
> >     @Post
> >     @HttpResource(location = "/message")
> >     public wsResponse<wsMessage> getMessage(
> >             @WebParam(name = "message")wsMessage message);
> >
> > }
> >
> > I am using this javascript:
> >
> > var json = {"wsMessage":{"messageId":"1"}};
> >
> > new Ajax.Request($F('url'), {
> >     asynchronous: false,
> >     method: 'post',
> >     contentType: 'application/json',
> >     postBody: Object.toJSON(json),
> >     onSuccess: function(transport,jsonFromHeaders)
> >
> > and in my beans.xml, I have this:
> >
> >
> > <jaxws:endpoint id="jBoardService"
> > implementor="com.cbs.bos.ws.json.BoardServiceImpl"
> > address="/jBoardService"
> > bindingUri="http://apache.org/cxf/binding/http">
> > <jaxws:properties>
> > <entry key="Content-Type" value="text/plain"/>
> > </jaxws:properties>
> > <jaxws:serviceFactory>
> > <bean class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
> > <property name="wrapped" value="false"/>
> > <property name="properties">
> > <map>
> > <entry>
> > <key><value>javax.xml.stream.XMLInputFactory</value></key>
> > <bean class="org.codehaus.jettison.mapped.MappedXMLInputFactory">
> > <constructor-arg>
> > <map>
> > <entry key="http://BoardService.json.bos.cbs.com/"
> > value="jBoardService"/>
> > <entry key="http://BoardServiceImpl.json.bos.cbs.com/"
> > value="jBoardServiceImpl"/>
> > </map>
> > </constructor-arg>
> > </bean>
> > </entry>
> > <entry>
> > <key><value>javax.xml.stream.XMLOutputFactory</value></key>
> > <bean class="org.codehaus.jettison.mapped.MappedXMLOutputFactory">
> > <constructor-arg>
> > <map>
> > <entry key="http://BoardService.json.bos.cbs.com/"
> > value="jBoardService"/>
> > <entry key="http://BoardServiceImpl.json.bos.cbs.com/"
> > value="jBoardServiceImpl"/>
> > </map>
> > </constructor-arg>
> > </bean>
> > </entry>
> > </map>
> > </property>
> > </bean>
> > </jaxws:serviceFactory>
> > </jaxws:endpoint>
> >
> >
> >
> > -----Original Message-----
> > From: Liu, Jervis [mailto:jliu@iona.com]
> > Sent: Tuesday, January 15, 2008 12:32 AM
> > To: cxf-user@incubator.apache.org
> > Subject: RE: Issues with JSON based Service and Jettison
> >
> > First of all, you need to set wrapped style to false, wrapped style true
> won't
> > work with JSON (I noticed that you already set wrapped to false). What
> > happened is Jettison reads input stream to a W3C Document, then this
> W3C
> > Document is used to create a new XMLInputStream. From this point on,
> the
> > following CXF interceptors will presume they are deal with a normal XML
> > input e.g. the XML section embedded in a soap body.
> >
> > Let's take a concrete example. An inputstream of
> > "{"acme.Book":{"acme.name":"CXF in Action "}}" is transferred to a
> > org.w3c.dom.Document of <Book><name>CXF in Action</name></Book>
> > by Jettison first, then the Document object will be marshaled to a Book
> > object. The wrapper I am talking about is referring to the operation name
> > wrapper of doc-lit wrapped style. For example, if you set wrapped style to
> > true, in order to marshal the Document to Book object successfully, the
> > Document's content need to be <addBook ><Book><name>CXF in
> > Action</name></Book></addBook> instead.
> >
> > Cheers,
> > Jervis
> >
> > > -----Original Message-----
> > > From: Vespa, Anthony J [mailto:ajvespa@cbs.com]
> > > Sent: 2008年1月14日 21:32
> > > To: cxf-user@incubator.apache.org; cxf-user@incubator.apache.org
> > > Subject: RE: Issues with JSON based Service and Jettison
> > >
> > > Hrm, could you explain a bit more please?
> > >
> > > I was under the impression from various examples that JSON would
> behave
> > > like REST, eg I pass a request in a URL and the response comes back as a
> > > JSON output (eg I have a method called getMessage and it takes 3
> params)
> > > so I pass it message/1/2/3/ and the output is in JSON forma- by the
> request
> > > wrapper you mean that I would need to pass it one object (say, a
> hashmap)
> > > and unwrap that object, as that is how the JSON inbound request is
> > > represented, correct?  I was under the perhaps mistaken impression
> that
> > > JSON was extracting the values from the inbound JSON array and
> matching
> > > them with the arguments via Jettison.
> > >
> > > ________________________________
> > >
> > > From: Liu, Jervis [mailto:jliu@iona.com]
> > > Sent: Sun 1/13/2008 5:00 AM
> > > To: cxf-user@incubator.apache.org
> > > Subject: RE: Issues with JSON based Service and Jettison
> > >
> > >
> > >
> > > According to the stack trace, it looks like your service method has more
> > than
> > > one parameters. The CXF HTTP binding requires that the service method
> > can
> > > only have one input parameters. For example, following is invalid:
> > >
> > >     @Put
> > >     @HttpResource(location = "/books/{id}")
> > >     void updateBook(@WebParam(name = "Book")Book c, int id);
> > >
> > > Hope this helps,
> > > Jervis
> > >
> > > > -----Original Message-----
> > > > From: Vespa, Anthony J [mailto:ajvespa@cbs.com]
> > > > Sent: 2008?1?13? 10:33
> > > > To: cxf-user@incubator.apache.org; cxf-user@incubator.apache.org
> > > > Subject: RE: Issues with JSON based Service and Jettison
> > > >
> > > > I actually tried the jax_rs samples a week or two back and it caused
> quite
> > a
> > > > few issues with our codebase, as well as generally not working - it
> would
> > > > also require re-writes of all services, but even just re-writing one I get
> > > > exceptions and other issues - there was also some odd behavior, like
> not
> > > > being able to pass any data type but a String, for example, as any
> > > > arguement.
> > > >
> > > > Has anyone got a good detailed example of getting JSON to work from
> > end
> > > > to end, with submitting a JSON formatted input into a service, and
> > getting
> > > > appropriate output, with a configuration through beans.xml?  I can
> get
> > > the
> > > > simple examples to work with some futzing around, but I'm doing to
> send
> > > > some complex input back and forth  I've scanned through the mailing
> > list
> > > > and searched the web, but I haven't found much info - the docs for
> > jettison
> > > > tend to give the same general example and I need something specific -
> or
> > > at
> > > > least a hard enough push to know if it is a configuration issue, or if I am
> > > > trying to do something that is either crazy or not supported.
> > > >
> > > > ________________________________
> > > >
> > > > From: Liu, Jervis [mailto:jliu@iona.com]
> > > > Sent: Sat 1/12/2008 11:36 AM
> > > > To: cxf-user@incubator.apache.org
> > > > Subject: RE: Issues with JSON based Service and Jettison
> > > >
> > > >
> > > >
> > > > Grab a latest snapshot of CXF, check out the
> > > > samples\jax_rs\content_negotiation demo. The spring configuration
> can
> > > be
> > > > found in [1]. An example of using JSON to do post can be found in
> system
> > > > test:
> > > >
> > >
> >
> trunk\systests\src\test\java\org\apache\cxf\systest\jaxrs\JAXRSClientServer
> > > > BookTest.java
> > > >
> > > > [1]. http://cwiki.apache.org/CXF20DOC/jax-rs-jsr-311.html
> > > >
> > > > Cheers,
> > > > Jervis
> > > >
> > > > > -----Original Message-----
> > > > > From: Vespa, Anthony J [mailto:ajvespa@cbs.com]
> > > > > Sent: 2008?1?12? 1:43
> > > > > To: cxf-user@incubator.apache.org
> > > > > Subject: Issues with JSON based Service and Jettison
> > > > >
> > > > > Hello,
> > > > >
> > > > > I cannot seem to get a JSON based servive to work properly.  Does
> > > > anyone
> > > > > have a complete end to end example using the spring config to set up
> > > > > jettison?  Ideally I want to be able to use a post or a get to a service
> > > > > using JSON both on request and response.
> > > > >
> > > > > I am accessing the service via /message/ABC123DEF456/4
> > > > > I am using Jettison and am getting the following exceptions:
> > > > >
> > > > > Jan 11, 2008 12:36:27 PM
> > > > > org.apache.cxf.interceptor.AttachmentInInterceptor handleMessage
> > > > > INFO: AttachmentInInterceptor skipped in HTTP GET method
> > > > > Jan 11, 2008 12:36:27 PM
> > > > > org.apache.cxf.binding.http.interceptor.DispatchInterceptor
> > > > > handleMessage
> > > > > INFO: Invoking GET on /message/ABC123DEF456/4
> > > > > Jan 11, 2008 12:36:27 PM
> > > > > org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor
> > > > > handleMessage
> > > > > INFO: URIParameterInterceptor handle message on path
> > > > > [/message/ABC123DEF456/4] with content-type [null]
> > > > > Jan 11, 2008 12:36:27 PM
> org.apache.cxf.phase.PhaseInterceptorChain
> > > > > doIntercept
> > > > > INFO: Interceptor has thrown exception, unwinding now
> > > > > org.apache.cxf.interceptor.Fault: SINGLE_PART_REQUIRED
> > > > >         at
> > > > >
> > >
> org.apache.cxf.binding.http.interceptor.URIParameterInInterceptor.handle
> > > > > Message(URIParameterInInterceptor.java:82)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorC
> > > > > hain.java:207)
> > > > >         at
> > > > >
> > >
> org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiati
> > > > > onObserver.java:78)
> > > > >         at
> > > > >
> > >
> org.apache.cxf.transport.servlet.ServletDestination.doMessage(ServletDes
> > > > > tination.java:79)
> > > > >         at
> > > > >
> > org.apache.cxf.transport.servlet.ServletController.invokeDestination(Ser
> > > > > vletController.java:264)
> > > > >         at
> > > > >
> > org.apache.cxf.transport.servlet.ServletController.invoke(ServletControl
> > > > > ler.java:123)
> > > > >         at
> > > > >
> > >
> org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFSe
> > > > > rvlet.java:170)
> > > > >         at
> > > > >
> > >
> org.apache.cxf.transport.servlet.AbstractCXFServlet.doGet(AbstractCXFSer
> > > > > vlet.java:152)
> > > > >         at
> > javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
> > > > >         at
> > javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
> > > > >         at
> > > > >
> > org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Applica
> > > > > tionFilterChain.java:290)
> > > > >         at
> > > > >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilt
> > > > > erChain.java:206)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperVa
> > > > > lv
> > > > > e.java:233)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValv
> > > > > e.java:175)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java
> > > > > :128)
> > > > >         at
> > > > >
> > >
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java
> > > > > :102)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.
> > > > > java:109)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:2
> > > > > 63)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:84
> > > > > 4)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
> > > > > ss(
> > > > > Http11Protocol.java:584)
> > > > >         at
> > > > >
> > >
> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
> > > > >         at java.lang.Thread.run(Thread.java:595)
> > > > > Jan 11, 2008 12:36:27 PM
> org.apache.cxf.phase.PhaseInterceptorChain
> > > > > doIntercept
> > > > > INFO: Interceptor has thrown exception, unwinding now
> > > > > java.lang.IllegalStateException: Invalid JSON namespace:
> > > > > http://cxf.apache.org/bindings/xformat
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.codehaus.jettison.mapped.MappedNamespaceConvention.getJSONNam
> > > > > espace(
> > > > > MappedNamespaceConvention.java:148)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.codehaus.jettison.mapped.MappedNamespaceConvention.createKey(M
> > > > > appedN
> > > > > amespaceConvention.java:155)
> > > > >         at
> > > > >
> > > >
> > >
> >
> org.codehaus.jettison.mapped.MappedXMLStreamWriter.writeStartElement(
> > > > > Map
> > > > > pedXMLStreamWriter.java:220)
> > > > >         at
> > > > >
> org.apache.cxf.staxutils.StaxUtils.writeStartElement(StaxUtils.java:182)
> > > > > )
> > > > >
> > > > >
> > > > > I set up my jettison properties in my beans.xml as such following
> other
> > > > > examples on this list:
> > > > >
> > > > >     <jaxws:endpoint id="jBoardService"
> > > > > implementor="com.cbs.bos.ws.json.BoardServiceImpl"
> > > > > address="/jBoardService"
> > > > > bindingUri="http://apache.org/cxf/binding/http">
> > > > > <jaxws:properties>
> > > > > <entry key="Content-Type" value="text/plain"/>
> > > > > </jaxws:properties>
> > > > > <jaxws:serviceFactory>
> > > > > <bean
> > class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
> > > > > <property name="wrapped" value="false"/>
> > > > > <property name="properties">
> > > > > <map>
> > > > > <entry>
> > > > > <key><value>javax.xml.stream.XMLInputFactory</value></key>
> > > > > <bean
> > class="org.codehaus.jettison.mapped.MappedXMLInputFactory">
> > > > > <constructor-arg>
> > > > > <map>
> > > > > <entry key="http://BoardService.json.bos.cbs.com/"
> > > > > value="jBoardService"/>
> > > > > <entry key="http://BoardServiceImpl.json.bos.cbs.com/"
> > > > > value="jBoardServiceImpl"/>
> > > > > </map>
> > > > > </constructor-arg>
> > > > > </bean>
> > > > > </entry>
> > > > > <entry>
> > > > > <key><value>javax.xml.stream.XMLOutputFactory</value></key>
> > > > > <bean
> > > class="org.codehaus.jettison.mapped.MappedXMLOutputFactory">
> > > > > <constructor-arg>
> > > > > <map>
> > > > > <entry key="http://BoardService.json.bos.cbs.com/"
> > > > > value="jBoardService"/>
> > > > > <entry key="http://BoardServiceImpl.json.bos.cbs.com/"
> > > > > value="jBoardServiceImpl"/>
> > > > > </map>
> > > > > </constructor-arg>
> > > > > </bean>
> > > > > </entry>
> > > > > </map>
> > > > > </property>
> > > > > </bean>
> > > > > </jaxws:serviceFactory>
> > > > > </jaxws:endpoint>
> > > >
> > > > ----------------------------
> > > > IONA Technologies PLC (registered in Ireland)
> > > > Registered Number: 171387
> > > > Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> > Ireland
> > > >
> > >
> > > ----------------------------
> > > IONA Technologies PLC (registered in Ireland)
> > > Registered Number: 171387
> > > Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> Ireland
> > >
> >
> > ----------------------------
> > IONA Technologies PLC (registered in Ireland)
> > Registered Number: 171387
> > Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
> 
> ----------------------------
> IONA Technologies PLC (registered in Ireland)
> Registered Number: 171387
> Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland