1 2 Previous Next 17 Replies Latest reply on Dec 14, 2005 10:34 AM by Stefan Frank

    Example for using XMLBeans for DataBinding?!

    Stefan Frank Newbie

      Does someone know a decent example how to configure a webservice in Jboss to use XMLBeans for Databinding? I'm not sure where to look at first, I found some examples for configuring Axis to use XMLBeans, but I don't know exactly how axis is tweaked to fit into jboss. Any pointers would be highly appreciated!!

      cheers
      stf

        • 1. Re: Example for using XMLBeans for DataBinding?!
          Ole Matzura Novice

          Hi!

          We've done this successfully on several projects with doc/literal webservices.. you need to do the following:

          - generate your servers/clients with the wscompile -nodatabinding option
          - generate xmlbeans classes from your wsdls using the xmlbeans ant-task
          - deserialize incoming SOAPElements using XmlObject.parse( Node n )
          - create outgoing SOAPElements using XmlObject.newDomNode() which you then convert to a SOAPElement (you can also use getDomNode() but you will have to do namespace attribute stuff yourself)

          With serialization/deserialization you have to use the XxxDocument classes generated by xmlbeans for your request/response global elements

          it's a piece of cake ! (once you have everything working ;-)

          If you're stuck on any of the above steps let me know and I'll try to help..

          regards,

          Ole

          • 2. Re: Example for using XMLBeans for DataBinding?!
            Stefan Frank Newbie

            Hi Ole,

            thats good news, that really sounds not so hard to do. I will try this right now, thx for the help.

            cheers

            • 3. Re: Example for using XMLBeans for DataBinding?!
              Stefan Frank Newbie

              Hi Ole,

              maybe you have encountered similar problems and can help: I ran upon some problems with wscompile when using complex types:

              I import the schema-file using:

              xmlns:orderTypes="urn-my-namespace/types"
              ....
              
              <types>
              <xs:schema elementFormDefault="qualified" targetNamespace="urn-my-namespace/types">
               <xs:import namespace="urn-my-namespace/types"
               schemaLocation="http://localhost:8080/order/types/order.xsd"/>
              </xs:schema>
              </types>
              


              and then construct a message using:

              <message name="OrderRequest">
               <part name="request" element="orderTypes:order" />
              </message>
              
              <portType name="SignupPort">
               <operation name="signup" >
               <input message="tns:OrderRequest" />
               <output message="tns:OrderResponse" />
               </operation>
              </portType>
              


              The wscompile works, but if generates a signup with an empty signature:

              public interface SignupPort extends java.rmi.Remote {
               public javax.xml.soap.SOAPElement signup() throws
               java.rmi.RemoteException;
              }
              


              At least, I would have assumed a SOAPElement in the signature - at least, that's what is generated for a simple type like xs:string (but only if I use a type in the part, not an element...)

              Maybe you have a quick idea, what's going wrong here?!

              Thx for the help!!
              Cheers
              stf


              • 4. Re: Example for using XMLBeans for DataBinding?!
                Ole Matzura Novice

                hmm.. hard to say.. what wscompile options are you specifying? what does the binding definition look like in the wsdl?

                we used the following wscompile options:
                -import
                -keep
                -f:nodatabinding
                -f:documentliteral
                -f:wsi

                together with doc/literal webservices.. does this match your setup?

                regards!

                /Ole

                • 5. Re: Example for using XMLBeans for DataBinding?!
                  Stefan Frank Newbie

                  ok, wsi was a good tip: At least I am now getting some serious error messages to work with, like:

                  [wscompile] warning: ignoring operation "signup": message part does not refer to a schema element declaration
                  [wscompile] warning: Port "tns:SignupPort" does not contain any usable operations
                  


                  And the error seems to be between somewhere between the porttype and the binding-definition:

                  <portType name="SignupPort">
                   <operation name="signup" >
                   <input message="tns:OrderRequest" />
                   <output message="tns:OrderResponse" />
                   </operation>
                   </portType>
                  
                   <binding type="tns:SignupPort" name="SignupBinding">
                   <soap:binding style="document"
                   transport="http://schemas.xmlsoap.org/soap/http" />
                  
                   <operation name="signup">
                   <soap:operation soapAction="" />
                   <input>
                   <soap:body use="literal" />
                   </input>
                   <output>
                   <soap:body use="literal" />
                   </output>
                   </operation>
                   </binding>
                  


                  The Messages (OrderRequest, OrderResponse) only contain simple references to elements defined in the external xsd:

                  <message name="OrderRequest">
                   <part name="request" element="orderTypes:myOrder" />
                  </message>
                  


                  There has to be an obvious error in this, but I seem to be to blind to see it....

                  Many thx for the help!
                  stf


                  • 6. Re: Example for using XMLBeans for DataBinding?!
                    Ole Matzura Novice

                    Hi!

                    for some reason wscompile cant find the orderTypes:myOrder element you are referring to in your message part.

                    have you imported/defined all namespace correctly and defined the specified global element ("myOrder") appropriately?

                    can you show us the complete wsdl/xsd(s)?

                    regards!

                    /Ole

                    • 7. Re: Example for using XMLBeans for DataBinding?!
                      Stefan Frank Newbie

                      Yes, sure, here is a shortened example: I have left omitted lots of the element definitions, as they are basically all the same:

                      <?xml version="1.0" encoding="UTF-8"?>
                      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
                       targetNamespace="http://specification.ullorder.de.netpioneer.com/types"
                       xmlns:ullorder="http://specification.ullorder.de.netpioneer.com/types" >
                      
                       <xs:element name="ullOrder">
                       <xs:annotation>
                       <xs:documentation>Schema for External Signup</xs:documentation>
                       </xs:annotation>
                       <xs:complexType>
                       <xs:sequence>
                       <xs:element ref="ullorder:customerData" minOccurs="1" maxOccurs="1"/>
                       <xs:element ref="ullorder:payment" minOccurs="1" maxOccurs="1"/>
                       <xs:element ref="ullorder:ullInfo" minOccurs="1" maxOccurs="1"/>
                       <xs:element ref="ullorder:orders" minOccurs="1" />
                       <xs:element ref="ullorder:phoneBookEntry" minOccurs="0" maxOccurs="unbounded"/>
                       <xs:element ref="ullorder:voice" />
                       </xs:sequence>
                       </xs:complexType>
                       </xs:element>
                      
                       <xs:element name="address">
                       <xs:complexType>
                       <xs:sequence>
                       <xs:element name="street" type="xs:string" minOccurs="1"/>
                       <xs:element name="streetNumber" type="xs:integer" minOccurs="1"/>
                       <xs:element name="floor" type="xs:string" minOccurs="1"/>
                       <xs:element name="roomnumber" type="xs:string" minOccurs="0"/>
                       <xs:element name="zip" type="xs:string" minOccurs="1"/>
                       <xs:element name="city" type="xs:string" minOccurs="1"/>
                       <xs:element name="country" type="xs:string" minOccurs="1"/>
                       <xs:element name="district" type="xs:string" minOccurs="0" />
                       <xs:element name="state" type="xs:string" minOccurs="0" />
                       </xs:sequence>
                       </xs:complexType>
                       </xs:element>
                      
                       ....
                      
                      </xs:schema>
                      


                      <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
                      <definitions
                       targetNamespace="http://specification.ullorder.de.netpioneer.com"
                       xmlns:tns="http://specification.ullorder.de.netpioneer.com"
                       xmlns="http://schemas.xmlsoap.org/wsdl/"
                       xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
                       xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
                       xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                       xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                       xmlns:xs="http://www.w3.org/2001/XMLSchema"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xmlns:orderTypes ="http://specification.ullorder.de.netpioneer.com/types"
                       >
                      
                       <types>
                       <xs:schema elementFormDefault="qualified" targetNamespace="http://specification.ullorder.de.netpioneer.com/types">
                       <xs:import namespace="http://specification.ullorder.de.netpioneer.com/types"
                       schemaLocation="http://localhost:8080/workflowsystem-web-0.1/types/ullOrder.xsd"/>
                      
                      
                       </xs:schema>
                       </types>
                      
                      
                       <message name="OrderRequest">
                       <part name="request" element="orderTypes:ullOrder" />
                       </message>
                      
                       <message name="OrderResponse">
                       <part name="response" type="xs:string" />
                       </message>
                      
                      
                       <portType name="SignupPort">
                       <operation name="signup" >
                       <input message="tns:OrderRequest" />
                       <output message="tns:OrderResponse" />
                       </operation>
                       </portType>
                      
                       <binding type="tns:SignupPort" name="SignupBinding">
                       <soap:binding style="document"
                       transport="http://schemas.xmlsoap.org/soap/http" />
                      
                       <operation name="signup">
                       <soap:operation soapAction="http://specification.ullorder.de.netpioneer.com/operations/signup" />
                       <input>
                       <soap:body use="literal" />
                       </input>
                       <output>
                       <soap:body use="literal" />
                       </output>
                       </operation>
                       </binding>
                      
                       <service name="SignupServices">
                       <port name="SignupPort" binding="tns:SignupBinding">
                       <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
                       </port>
                       </service>
                      
                      </definitions>
                      


                      Does this help to see the error?!

                      cheers
                      stf

                      • 8. Re: Example for using XMLBeans for DataBinding?!
                        Stefan Frank Newbie

                        Got it!

                        I found this funny little note:
                        http://archives.java.sun.com/cgi-bin/wa?A2=ind0308&L=jaxrpc-interest&F=&S=&P=2115

                        and then found, that *not* this is the root of all evil:

                        <message name="OrderRequest">
                         <part name="request" element="orderTypes:ullOrder" />
                        </message>
                        


                        but this:
                        <message name="OrderResponse">
                         <part name="response" type="xs:string" />
                        </message>
                        


                        The note says:
                        "For a document/literal operation, the part should refer a schema element using the 'element' attribute."


                        therefore, the request was right all the time, but the reponse was formulated wrongly for a document/literal. Changing the reponse to something like:

                        <message name="OrderResponse">
                         <part name="response" element="orderTypes:SignupResponse" />
                        </message>
                        


                        fixes this. Now the Port-Classes and _Impl are generated with the correct Signature for an anbounded, document/literal service:

                        public javax.xml.soap.SOAPElement signup(javax.xml.soap.SOAPElement request) throws
                         java.rmi.RemoteException {
                        
                         javax.xml.soap.SOAPElement _retVal = null;
                         return _retVal;
                         }
                        


                        and I can hopefully start pluggin in my XMLBeans-Code...

                        Sorry for starting so much confusion and many thx for the help, Ole - without the hint to use wsi I would still be debugging my XSD's...

                        Cheers
                        stf


                        • 9. Re: Example for using XMLBeans for DataBinding?!
                          Anil Saldanha Master

                          Please have a look at the JBossXB project that JBoss internally uses for xml binding.

                          • 10. Re: Example for using XMLBeans for DataBinding?!
                            Stefan Frank Newbie

                            Hi Anil,

                            thx, I looked at it, but I don't think it's an imporvement over XMLBeans, due to several reasons - please correct me, if I've gotten something wrong:

                            - there is no xsd->java compile, that generates the Holder-Objects for a given schema. Instead I have to write the objects, that I want to map my xml into by hand.

                            - Implementation details about the used mapping are leaking into the XSD ( in form of xsd:annotation) This is fine, as it reduces the number of files needed for configuration, but which is bad, if you want to use your xsd as contracts for your external clients (as is the case with using the xsd inside the wsdl) - I certainly do not want to change my wsdl, when I decide upon a different mapping-strategy.

                            - I haven't found anything to validate an incoming XML against the xsd - did I miss the corresponding api-calls?

                            - I still have to use document/literal with nodatabinding and deserialize/serialize my SOAPElements by hand: Or is there a simple configuration-mechanism to use JBossXB for serialiazation/deserialization? I have to do this by hand with XMLBeans too, but something similar to the typeMapping in Axis' WSDD would be nice...

                            Do you know by any chance, if these requirements have found their way into the new JBossWS?

                            cheers
                            stf

                            • 11. Re: Example for using XMLBeans for DataBinding?!
                              Stefan Frank Newbie

                              Hi Ole,
                              could you please elaborate a little bit more (maybe with an abbreviated code-example) on:


                              create outgoing SOAPElements using XmlObject.newDomNode() which you then convert to a SOAPElement (you can also use getDomNode() but you will have to do namespace attribute stuff yourself)


                              I'm currently struggling with finding the right combination of SOAPElementFactory, getDomNode() etc without hitting upon NullPointerExceptions...

                              thx!
                              stf


                              • 12. Re: Example for using XMLBeans for DataBinding?!
                                Ole Matzura Novice

                                Hi!

                                what jboss version are you using? (we have a patched 4.0.2 with some internal optimizations.. )..

                                anyway.. here comes our method for converting the DOM node returned from XmlObject.newDomNode() to a SOAPElement

                                its a bit taken out of context.. so I hope it will help :-)

                                regards,

                                /Ole

                                /**
                                 * Creates a SOAPElement from the specified DOM node using the specified SOAPFactory
                                 *
                                 * @param domNode the domNode to create for
                                 * @param factory the SOAPFactory to use for node creation.
                                 * @param isRpc if set to true then the top node will be unqualified
                                 * @return the created SOAPElement, <code>null</code if creation fails.
                                 * @throw Exception on internal errors
                                 */
                                
                                 public static SOAPElement createSOAPElement(org.w3c.dom.Node domNode, SOAPFactory factory, boolean isRpc) throws Exception
                                 {
                                 try
                                 {
                                 if( factory == null )
                                 factory = SOAPFactory.newInstance();
                                
                                 // Test that DOMNode is of type org.w3c.dom.Node.ELEMENT_NODE.
                                 if ((domNode.getNodeType()) != org.w3c.dom.Node.ELEMENT_NODE)
                                 throw new Exception("DOMNode must of type ELEMENT_NODE");
                                
                                 String prefix = domNode.getPrefix();
                                 String namespaceURI = domNode.getNamespaceURI();
                                
                                 SOAPElement se;
                                 if (isRpc || prefix == null || prefix.length() == 0 )
                                 {
                                 se = factory.createElement(factory.createName(domNode.getLocalName()));
                                 }
                                 else
                                 {
                                 se = factory.createElement(domNode.getLocalName(), prefix, namespaceURI);
                                 }
                                
                                 if (domNode.hasAttributes())
                                 {
                                 NamedNodeMap DOMAttributes = domNode.getAttributes();
                                 int noOfAttributes = DOMAttributes.getLength();
                                 for (int i = 0; i < noOfAttributes; i++)
                                 {
                                 org.w3c.dom.Node attr = DOMAttributes.item(i);
                                
                                 prefix = attr.getPrefix();
                                 namespaceURI = attr.getNamespaceURI();
                                
                                 Name name = prefix == null || prefix.length() == 0 ? factory.createName(attr.getLocalName()) : factory
                                 .createName(attr.getLocalName(), prefix, namespaceURI);
                                
                                 se.addAttribute(name, attr.getNodeValue());
                                 }
                                 }
                                
                                 if (domNode.hasChildNodes())
                                 {
                                 NodeList children = domNode.getChildNodes();
                                 for (int i = 0; i < children.getLength(); i++)
                                 {
                                 org.w3c.dom.Node child = children.item(i);
                                
                                 switch (child.getNodeType())
                                 {
                                 case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
                                 break;
                                
                                 case org.w3c.dom.Node.DOCUMENT_TYPE_NODE:
                                 break;
                                
                                 case org.w3c.dom.Node.COMMENT_NODE:
                                 break;
                                
                                 case org.w3c.dom.Node.CDATA_SECTION_NODE:
                                
                                 case org.w3c.dom.Node.TEXT_NODE:
                                 {
                                 if (children.getLength() == 1)
                                 se.addTextNode(child.getNodeValue());
                                 break;
                                 }
                                
                                 default:
                                 {
                                 se.addChildElement(createSOAPElement(child, factory));
                                 }
                                 }
                                
                                 }// end of for
                                 }// end of if
                                
                                 return se;
                                 }
                                 catch (Exception e)
                                 {
                                 e.printStackTrace();
                                 throw new Exception("Failed to create SOAP element from DOM node", e);
                                 }
                                 }
                                


                                • 13. Re: Example for using XMLBeans for DataBinding?!
                                  Stefan Frank Newbie

                                  ok, this is starting to look like work:) - Do you have by any chance seen this error:

                                  javax.xml.soap.SOAPException: org.jboss.axis.AxisFault: The prefix "xmlns" cannot be bound to any namespace explicitly; neither can the namespace for "xmlns" be bound to any prefix explicitly.
                                   at org.jboss.axis.MessagePart.getEnvelope(MessagePart.java:1107)
                                   ...
                                  


                                  What bothers me, is the fact, that jboss complains about the envelope. The SOAPElement itself seems to be ok, as I can still parse it with XMLBeans, even after the createSOAPElement. I'm using:

                                  SignupPort signupPort = (SignupPort)signupPort_Stub;
                                  File orderXML = new File("src/test/resources/order.xml");
                                  UllOrderDocument orderDocument = UllOrderDocument.Factory.parse(orderXML);
                                  
                                  Element el = ((Document)orderDocument.getDomNode()).getDocumentElement();
                                  SOAPElement element = createSOAPElement(el, SOAPFactory.newInstance(), false);
                                  


                                  to get from my XML to a SOAPElement and finally send it away using:
                                  signupPort.signup(element);
                                  


                                  Has anybody seen this error?!

                                  cheers
                                  stf

                                  • 14. Re: Example for using XMLBeans for DataBinding?!
                                    Ole Matzura Novice

                                    hm...

                                    have you tried to use newDomNode instead of getDomNode? the internl ws-stack in jboss 4.0.x has had a lot of problems with namespaces, xsi-types, etc.. the DOM tree emitted by newDomNode has worked better for us at least..

                                    /Ole

                                    1 2 Previous Next