I need to generate a web service which matches a specification. In that spec, there are a lot of places I need...
to add attributes to some XML tags. Basically I'm using XML-RPC in that I use Java objects instead of dealing with XML data directly.
- How can I declare a field in the Java object class to be an attribute rather than a element (subtag)?
- How do I generate the WSDL file which indicates the attributes of some fields?
By "XML-RPC" I assume you mean SOAP RPC style rather than the XML-RPC protocol. (XML-RPC isn't SOAP. It's a completely different protocol.)
In any case, if you want to use attributes, you can't use SOAP RPC style -- it doesn't support attributes. You must use Document/Literal style.
From a programming perspective, there's very little difference between RPC/Encoded and Document/Literal styles. The style really only affects the format of the message on the wire. Most Web services platforms now support automatic serialization and deserialization of Doc/Literal messages into Java objects.
You should start by defining an XML Schema that reflects your specification. Then write a WSDL document, and either paste the schema into the WSDL <types> section, or import it using a schema <import>. (I suggest that you use a Schema/WSDL editor to help you write the schema and WSDL. Cape Clear provides a free one -- but it tends to load up your WSDL file with Cape Clear-specific structures. Kamiak OmniOpera and Altova XML Spy provide a lot more functionality, and they're platform agnostic.)
To support a more natural RMI-like experience, you want to design your WSDL to support what's known as "wrapped" style. You do so by making your operation name the same as the name of the element specified in the input message. e.g.:
<wsdl:definitions ...> <wsdl:types ...> <xsd:schema ...> <xsd:element name="foobar"> <xsd:complex type> <xsd:sequence> <xsd:element name="foo" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="bar" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="foobarRequest"> <wsdl:part name="body" element="tns:foobar"/> </wsdl:message> ... <wsdl:portType name="foobarInterface"> <wsdl:operation name="foobar"> <wsdl:input message="tns:foobarRequest"> ... </wsdl:operation> </wsdl:portType> ... </wsdl:definitions>
Once you have your WSDL file written, use your platform's WSDL compiler (wsdl2java, wscompile, etc.) to generate a server skeleton and the client interface/proxy/stub. Fill in the appropriate code and give it a try. If you have trouble, I recommend using the Mindreef SOAPscope diagnostic tool.
One piece of advice: Make sure you're using the latest version of your Web service platform. The Apache Axis tools are still a little buggy. Don't even try to use Apache SOAP. If you're using Sun's JWSDP, make sure you download 1.2 (use JAX-RPC v1.1 EA). But for best results, I recommend using a commercial product, such as BEA WebLogic, Systinet WASP, or The Mind Electric GLUE. These products have much more comprehensive support for Doc/Literal.
Dig Deeper on Topics Archive
Related Q&A from Anne Thomas Manes
Anne Thomas Manes explains the differences between open source clients and open source implementations. Continue Reading
Anne Thomas Manes discusses the best way to go about creating an enterprise data dictionary and why the systems works well. Continue Reading
Anne Thomas Manes explains the difference between 'hard' real time and 'live' real time systems. Continue Reading