| Creation Date: | April 4, 2002 |
| Status: | Production |
| Version: | PDK Release 2 (9.0.2 and later) |
PDK-Java v2 provides an out-of-the-box service for invoking Web Services. It provides an abstraction to handle communication with web services. It allows you to declaratively invoke web services with the built-in web services renderer classes that it provides.
With PDK-Java, you can invoke both procedure-oriented RPC style web services as well as document-oriented Doc style web services. For DOC style services, the SOAP body carries a generic XML document, whereas in RPC style services, there's an explicit concept of "method invocation" coming into play. PDK-Java supports both these styles with specialized renderer classes.
The PDK-Java web service renderers are an extension to the basic portlet renderer framework designed to allow you to expose existing web services as portlets with the minimum of effort. By building on the same declarative portlet building approach that is used throughout the JPDK, the renderers provide a powerful way of "wiring in" almost any SOAP-based web service to Oraclie 9iAS Portal.
This document explains how you can build portlets using web services with the PDK-Java toolkit and its built-in renderers. For answers to frequently asked questions and background information read the Web Services FAQ.
You have installed PDK-Java as described in the article Installing the PDK-Java Framework and samples
You are familiar with portlet basics and the concept of a renderer. If this is not the case, see the article How to Build a Java Portlet.
You've seen sample web services portlets provided as part of PDK-Java, and have followed the instructions provided in Installing the Web Services Sample Portlets.
You have a basic understanding about using web services in portlets as described in the article Understanding Web Services for Portlets.
To build a portlet using a Web Service, you need to follow the following three main steps:
For building your own Web Service, you can use Oracle9i JDeveloper which has a great feature set especially for web services. The Web Services Description Language (WSDL) is an XML vocabulary that provides a standard way of describing Web Service details like the service location, method parameters and data types With Jdeveloper, you can use features like the client stub generation wizard that takes a WSDL URL and generates the stub class automatically. This stub class provides a wrapper for communication between the Portal and the Web Service.
So you can use JDeveloper to complement the capability of invoking web services. For an RPC style web service, you need you need to to use the built-in RPCWebServiceRenderer class, and fill in relevant tags in the provider.xml.
For a DOC style Web Service, you need to to use the built-in DocWebServiceRenderer class.
First, you need to select the web service that you plan to expose as a portlet. You may use a formal UDDI registry service, or a web site such as xmethods.net to locate a suitable web service.
Next, you need to establish the interface that the web service supports. The interface of a web service is generally described using an XML language called Web Services Description Language or WSDL. The URL to a WSDL document should be one of the attributes published for the web service you located.
Among other interface properties, a WSDL document defines the set of 'bindings' the web service supports, i.e. the different protocol formats through which it can be invoked. To be compatible with the PDK-Java web service renderers, the service must support a Simple Object Access Protocol (SOAP) binding, and hence should have a <binding> element in its WSDL document which contains a <soap:binding> element. The <soap:binding> element defines an important characteristic of the SOAP protocol binding which will determine which of the PDK-Java web service renderers you should select for rendering the web service.
Once you have decided on which style of SOAP binding the web service supports, and hence which renderer class you should use, you need to "wire it in" to a portlet. The following subsections explain how you would do this for both RPCWebServiceRenderer and DocWebServiceRenderer.
RPCWebServiceRenderer builds on the automated support for RPC style web services built in to Oracle JDeveloper version 9.0.2 and later. It assumes that you have used JDeveloper to analyze the web service's WSDL document and automatically generate a 'stub' or 'proxy' class for the web service which translates from Java method calls into remote procedure calls on the web service. Consult the JDeveloper section of otn.oracle.com to find out how to download JDeveloper, and consult the JDeveloper online help for details of how to generate web service stubs.
Once you have the Java stub for your RPC web service, you just need to tell RPCWebServiceRenderer which of the methods on the stub it should call, and what parameters to pass to the method (if any). This is done in the XML provider definition. An extract from the sample provider.xml showing the declaration for the stock quote portlet is shown below.
<showPage class="oracle.portal.provider.v2.webservice.RPCWebServiceRenderer">
<contentType>text/html</contentType>
<logging>false</logging>
<className>oracle.portal.sample.v2.devguide.webservices.NetXmethodsServicesStockquoteStockQuoteServiceStub</className>
<renderMethod>getQuote</renderMethod>
<param class="oracle.portal.provider.v2.webservice.WebServiceRenderer$URLParam">
<name>symbol</name>
<default>ORCL</default>
<prompt>Please enter a stock symbol</prompt>
</param>
<responseXSL>stockQuoteResponse.xsl</responseXSL>
</showPage>
|
As you can see, the Java class name of the stub is specified using the className element, and the method to call on the stub is specified using the renderMethod element.
There is also an element called responseXSL which defines the name of the XSL stylesheet used to transform the web service response into portlet markup. The stylesheet is stored in the same directory as the XML provider definition. Although this filename must be specified, the file need not exist, as the renderer will generate you a default XSL stylesheet if one is not already present. Once you have this basic stylesheet, you may later decide to 'fine tune' the porlet presentation by customizing the XSL for yourself.
Each parameter into the render method is declared in order using a param element. To declare a parameter bound to a constant value, you can use the param element in its 'simple' form, e.g.:
<param>123</param>
Note that you don't have to specify type information for each parameter - the parameter value is automatically converted into the appropriate type according to the argument list of the method.
To declare a parameter sourced from elsewhere, you have to use the param element in 'extended' from by specifying a class attribute with one of the following values (consult the PortletRenderRequest Javadoc for more details):
For each of the above parameter binding types, you can also specify extra properties in child elements of the param element, allowing extra control over the parameter binding:
For URL parameters, you can also use a special property called prompt to define the prompt to use for a field which accepts the value of the parameter in an HTML form. This property is used to drive the generation of the default XSL stylesheet which presents the web service output.
Because the structure of the XML sent to a doc style web service is far less constrained than that sent to an RPC style seb service, it is not so easy to generate a 'stub' class for a doc style web service that packages up all the 'arguments' into the web service into the appropriate XML structure. For this reason, DocWebServiceRenderer takes over the role of the stub as well as the portlet renderer, and uses a powerful extension to the provider.xml syntax to define argument bindings into an arbitrary XML structure.
As an example, an extract from the sample provider.xml showing the declaration for the "Who Is" portlet is included below.
<showPage class="oracle.portal.provider.v2.webservice.DocWebServiceRenderer">
<contentType>text/html</contentType>
<logging>false</logging>
<endpointURL>http://www.esynaps.com/WebServices/WhoIsService.asmx</endpointURL>
<soapAction>http://tempuri.org/WhoIs</soapAction>
<literal class="oracle.portal.provider.v2.webservice.LiteralXML"
handler="oracle.portal.provider.v2.webservice.LiteralXML$Handler">
<element name="WhoIs">
<attribute name="xmlns">http://tempuri.org/</attribute>
<element name="DomainName"
bind="urlParams/domainName"
default="oracle.com"
prompt="Please enter an Internet Domain name"/>
</element>
</literal>
<!-- This service produces HTML as output, so don't escape tag information -->
<escapeOutput>false</escapeOutput>
<responseXSL>whoIsResponse.xsl</responseXSL>
</showPage> |
This time, the endpointURL element defines the URL through which the web service is contacted and the soapAction element defines the value to be set for the SOAPAction HTTP header, if required. These attributes can easily be obtained from inspection of the WSDL document of the web service. The endpoint URL is specified within the <soap:address> element, while the SOAP Action should be specified in the soapAction attribute of the <soap:operation> element corresponding to the particular operation you want to invoke.
As well as specifying the parameter bindings into a doc style web service you must also specify the XML structure into which the values should be inserted. This is done using the literal element of the provider definition. A literal declaration should always begin as follows:
<literal class="oracle.portal.provider.v2.webservice.LiteralXML" handler="oracle.portal.provider.v2.webservice.LiteralXML$Handler">
This tells the provider definition processing code to hand over control to the special 'node handler' called LiteralXML$Handler, which is capable of processing the structured XML descriptions. Inside the literal element, you can use a combination of nested <element> and <attribute> elements to convey the structure of the XML and its bindings.
The <attribute> element describes an XML attribute whose name is specified by its name attribute. An <attribute> element can optionally contain text, corresponding to a constant value for the attribute.
Similarly, the <element> element describes an XML element whose name is specified by its name attribute. An <element> can optionally contain text, corresponding to constant textual content of the element, <attribute> elements, corresponding to attributes set on the element and further child <elements> corresponding to nested elements.
Both <element>s and <attribute>s can be 'bound' to dynamic content described by a bind attribute. A bind attribute should consist of a type name and a parameter name separated by a '/' character. As per RPCWebServiceRenderer, the bind type name controls where the bound value is sourced from and the same set of sources are supported. The allowed bind type names and their meanings are listed below:
Both <element> and <attribute> also support prompt and mandatory attributes, which have the same meaning as per RPCWebServiceRenderer.
This may all sound rather complicated, but you should find that the syntax is fairly intuitive. For example, the literal element above describes an XML structure that looks like the following:
<WhoIs xmlns="http://tempuri.org/">
<DomainName>oracle.com</DomainName>
</WhoIs>
As mentioned earlier, knowledge of XSL and XSLT is not required in order to get basic results from the renderers. However, by writing custom XSL, a user can gain more control over the markup generated by the renderer, and can present structured information more effectively, e.g. in an HTML table.
To be able to write appropriate XSL to present your web service results, you need some knowledge of the structure of the XML document which is passed through the XSLT transformation. An example listing is included below.
<doc>
<request>
<user>
<name>PORTAL30</name>
<authLevel>10</authLevel>
</user>
<formActionLink>http://my.host.com:7778/servlet/page</formActionLink>
<parameterPrefix>703031269.2.1704_STOCKQUOTE_703031269.</parameterPrefix>
<locale>
<country></country>
<language>en</language>
</locale>
<requestPath>http://my.host.com:7778/jpdk/</requestPath>
<pageURL>http://my.host.com:7778/servlet/page?_pageid=785&_dad=p30980&_schema=PORTAL30</pageURL>
</request>
<pageParams>
<param>
<name>_pageid</name>
<value>785</value>
</param>
<param>
<name>_dad</name>
<value>p30980</value>
</param>
<param>
<name>_schema</name>
<value>PORTAL30</value>
</param>
</pageParams>
<urlParams>
<param>
<name>_portal_id</name>
<value>70303</value>
</param>
<param>
<name>_user</name>
<value>PORTAL30</value>
</param>
<param>
<name>_render_mode</name>
<value>1</value>
</param>
<param>
<name>_provider_id</name>
<value>703031269</value>
</param>
<param>
<name>_auth_level</name>
<value>10</value>
</param>
<param>
<name>_portlet_id</name>
<value>2</value>
</param>
<param>
<name>_instance_name</name>
<value>1704_STOCKQUOTE_703031269</value>
</param>
<param>
<name>_design_url</name>
<value>http://my.host.com:7778/servlet/page?_dad=p30980&_schema=PORTAL30&_type=portlet&_providerid=703031269&_portletid=2&_referencepath=1704_STOCKQUOTE_703031269&_backurl=http%3A%2F%2Fwebdbsvr2.us.oracle.com%3A30980%2Fservlet%2Fpage%3F_pageid%3D785%26_dad%3Dp30980%26_schema%3DPORTAL30</value>
</param>
<param>
<name>_back_url</name>
<value>null</value>
</param>
<param>
<name>_login_url</name>
<value>http://my.host.com:7778/pls/p30980_sso/portal30_sso.wwsso_app_admin.fapp_process_login?p_app_id=</value>
</param>
<param>
<name>_page_url</name>
<value>http://my.host.com:7778/servlet/page?_pageid=785&_dad=p30980&_schema=PORTAL30</value>
</param>
<param>
<name>_border</name>
<value>1</value>
</param>
<param>
<name>_action</name>
<value>showPortlet</value>
</param>
<param>
<name>_has_title</name>
<value>1</value>
</param>
</urlParams>
<session>
<attribute>
<name>some_attribute</name>
<value>some_value</value>
</attribute>
</session>
<editData>
<attribute>
<name>some_item</name>
<value>some_value</value>
</attribute>
</editData>
<bindings>
<param>
<name>symbol</name>
<value>ORCL</value>
</param>
</bindings>
<response>
<return>48.5</return>
</response>
</doc>
|
As you can see, below the main document element, doc, there are seven main elements. The function of each of these elements is explained below:
To get an idea of how you might transform such a document into a portlet, have a look at the XSL files for the sample portlets in j2ee/home/applications/jpdk/jpdk/WEB-INF/providers/webservices.
Not everyone gets their XSL and parameter bindings correct first time, so to help debugging, the WebServiceRenderers have the following features:
For answers to frequently asked questions and background information read the Web Services FAQ.
Ultimately, your choice of the type of information storage depends on the nuances of your specific application. Oracle9iAS Portal provides support for all these different types of storages so you can build an optimum solution.
| Revision History: |
|
| Oracle Corporation World Headquarters 500 Oracle Parkway Redwood Shores, CA 94065, USA http://www.oracle.com/ |
Worldwide Inquiries: 1-800-ORACLE1 Fax 650.506.7200 |
Copyright and Corporate Info |