Sunday, December 07, 2003


Web Services Tip: JDeveloper Doc/Lit

Common question ... how do I publish doc/literal Web services in JDeveloper 9.0.3/9.0.4. 

The OC4J 10.0.3 JAX-RPC preview tutorial showing the Web services extension for JDeveloper 10.0.3 showed it as a one click option not available in JDeveloper 9.0.3/9.0.4.

The Oracle Application Server 10g 9.0.3/9.0.4 Web Services Assembler (see chapter 6) gives a set of options to do this from the command line but they too are not available in JDeveloper 9.0.3/9.0.4.  So how does it work?

First, build your class to accept and return an XML Element - here is a trivial example to show the concept:

package com.doc;
import org.w3c.dom.Element;
public class Echo
{
  public Element echoElement(Element p)
  {
    return p;
  }
}

Run it through the JDeveloper Web Services wizard as normal (see full tutorial on this for "Hello World"), publishing the echoElement() method as a Web service.

You will get a generated web.xml file, configuring the Oracle Application Server Web Services runtime servlet as follows:

<servlet>
    <servlet-name>EchoService</servlet-name>
    <servlet-class>oracle.j2ee.ws.StatelessJavaRpcWebService</servlet-class>
    <init-param>
      <param-name>class-name</param-name>
      <param-value>com.doc.Echo</param-value>
    </init-param>
    <init-param>
      <param-name>interface-name</param-name>
      <param-value>com.doc.IEchoService</param-value>
    </init-param>
  </servlet>

Correspondingly, you will get a WSDL generated, with the following binding and operation section:

   <binding name="EchoBinding" type="tns:EchoPortType">
      <soap:binding style="rpc" transport="
http://schemas.xmlsoap.org/soap/http"/>
      <operation name="echoElement">
         <soap:operation soapAction="" style="rpc"/>
         <input name="echoElement0Request">
            <soap:body use="literal" namespace="EchoService"/>
         </input>
         <output name="echoElement0Response">
            <soap:body use="literal" namespace="EchoService"/>
         </output>
      </operation>
   </binding>

So even though you have built something that implementation wise really looks like doc/literal (i.e. inbound and outbound XML document), what came out the otherside of the Web services wizard in JDeveloper is rpc/literal.

The steps to turn this into doc/literal are turn out to be trivial:

  1. In the web.xml, replace

    oracle.j2ee.ws.StatelessJavaRpcWebService

    with

    oracle.j2ee.ws.StatelessJavaDocWebService

  2. Next, JDeveloper generates a Web services deployment object, by default named Webservices.deploy in your project.  Right mouse click on it and select Settings or Properties (depending on your version of JDeveloper). 

    Navigate to the WEB-INF\classes node and *deselect* the generated WSDL file - in my case named IEchoService.wsdl - this WSDL has the RPC settings and we don't want to deploy it.  By not deploying it, the server will re-generate the WSDL.  Given our web.xml configuration says document, it will generate doc//literal WSDL.

  3. Next, deploy as usual by right mouse clicking on the Webservices.deploy and deploying to your OC4J - or take the produced ear file and use DCM or Enterprise Manager to deploy to a full fledged install of the Oracle Application Server.

Copy the Web service endpoint URL (in the JDeveloper Web service wizard, this is normally found in the third step/tab, "File Locations", in the field labelled "Web Service Endpoint") to an IE/Mozzilla browser and add a ?WSDL suffix on it.  In my case that is:

http://127.0.0.1:8888/ws/EchoService?WSDL

You will notice that the WSDL now reports that your previously generated rpc/literal Web service is now doc/literal:

- <binding name="IEchoServiceBinding" type="tns:IEchoServicePortType">
  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
- <operation name="echoElement">
  <soap:operation soapAction="urn:oracle:echoElement" />
- <input>
  <soap:body use="literal" namespace="urn:com-doc-IEchoService" />
  </input>
- <output>
  <soap:body use="literal" namespace="urn:com-doc-IEchoService" />
  </output>
  </operation>
  </binding>
- <service name="IEchoService">
 
AAnd with that, you are done.  One doc/literal Web service, served up.  More tips coming up this week.


comment []
8:54:19 PM