!--a11y-->
Programming a Web Service Client
Application 
To use a Web service in an application you must program a Web service client application.
You have generated a standalone or deployable proxy.
Additional information is available under Creating a Deployable Proxy and Creating a Standalone Proxy.
...
1. Access the implementation class of the service interface.
If you have generated a deployable proxy, you must use a JNDI lookup to access the service interface implementation. From the service interface, you have access to SEI. The SEI contains service Web service methods that can be used for client programming.
If you have generated a standalone proxy, the implementation class of the Service Interface is instantiated using the default constructor. Use the implementation class to receive a stub that implements the service endpoint interface (SEI).
The following example shows the access to the implementation class for standalone and deployable proxies:

The following assignments apply for the program sections:
· Name of service interface – MyService
· Name of service implementing class – MyServiceImpl
· Name of SEI – MyConfiguration
· Name of logical port – MyConfigurationLogicalPort
·
JNDI name – Myservice
Access the implementation class as follows:

import javax.naming.*;
public void callWebService() throws Exception { //get service (J2EE Case) MyService ms = (MyService new InitialContext ().lookup “java:comp/env/MyService”);
//get service (standalone case) MyService ms = new MyServiceImpl(); |
2. Create the instance of a logical port.

Use the following coding:

MyConfiguration mcl = (MyConfiguration)ms.getLogicalPort(MyConfiguration.class);
//get a named logical port
MyConfiguration mc2 = (MyConfiguration)ms.getLogicalPort (“MyConfigurationLogicalPort”, MyConfiguration.class); |
3. Invoke the business methods.
After you get the reference to the Logical Port / SEI, you can invoke the business methods.
Use the following coding:

//request a business method mcl.businessMethod(); |
This client uses classes that are generated by the proxy generator and that follow some patterns in class generation. Here is the code of the EchoService:

package echoservice;
public interface EchoService extends javax.xml.rpc.Service { public java.rmi.Remote getLogicalPort(String portName, Class seiClass) throws javax.xml.rpc.ServiceException; public java.rmi.Remote getLogicalPort(Class seiClass) throws javax.xml.rpc.ServiceException; } |
This interface extends the Service interface and, in this case, is used for obtaining port instances. The implementation of this interface can be found in the EchoServiceImpl class. Here is the code of EchoServiceVi:

package echoservice; import javax.xml.rpc.holders.*;
public interface EchoServiceVi extends java.rmi.Remote,javax.xml.rpc.Stub { public java.lang.String echoString(java.lang.String str) throws java.rmi.RemoteException; public java.lang.String[] echoStringArray(java.lang.String[] array) throws java.rmi.RemoteException; public echoservice.types.p2.StructA echoStructA(echoservice.types.p2.StructA param) throws java.rmi.RemoteException; public echoservice.types.p2.StructA[] echoStructAArray(echoservice.types.p2.StructA[] array) throws java.rmi.RemoteException; public echoservice.types.p2.StructB echoStructB(echoservice.types.p2.StructB param) throws java.rmi.RemoteException; public void throwCheckedException(echoservice.types.p2.StructA param) throws java.rmi.RemoteException,echoservice.MyException; } |
This is a Web service port interface representation also named Service Endpoint Interface. It contains all Web service methods that are available. In this example, the classes StructA and StructB are classes derived from WSDL Schema. The generated interface extends the java.rmi.Remote interface and the javax.xml.rpc.Stub interface. The first interface indicates a remote procedure call, the second interface provides access to some important implementation settings.
In the Service Interface you can see methods for getting the logical port only. The method getLogicalPort(Class seiClass) is used for container-managed port access and the getLogicalPort(String portName, Class seiClass) method enables you to select specific logical ports. The seiClass is required to obtain an application class loader. For more information about the available logical ports, see the lports.xml file in the SAP NetWeaver Developer Studio.
The following code fragment obtains a proxy instance and makes a single call to a Web service method:

package echoservice; /** * Simple Proxy Tester. */ public class Tester { public static void main(String[] args) throws Exception { EchoService service = new EchoServiceImpl(); EchoServiceVi port = (EchoServiceVi) service.getLogicalPort("EchoServiceSoapPortrpc_enc",EchoServiceVi.class); String param = "Hello World!"; String result = port.echoString(param); System.out.println("call to [.echoString]:"+param); System.out.println("result [.echoString]:"+result); } } |
Here is the result of this program:
call to
[.echoString]:Hello World!
result [.echoString]:Hello
World!
Now you are ready to use your first Web service client. If you use JAX-RPC compatible option in the NetWeaver Developer Studio, additional methods for getting the SEI implementations are available. The example below contains such method –getEchoServiceSoapPortrpcEnc:

package echoservice;
public interface EchoService extends javax.xml.rpc.Service { public echoservice.EchoServiceVi getEchoServiceSoapPortrpcEnc() throws javax.xml.rpc.ServiceException ; public java.rmi.Remote getLogicalPort(String portName, Class seiClass) throws javax.xml.rpc.ServiceException; public java.rmi.Remote getLogicalPort(Class seiClass) throws javax.xml.rpc.ServiceException; } |
This method enables you to get a specific port directly. Here is the client code using the new method:

package echoservice;
public class Tester { public static void main(String[] args) throws Exception { EchoService service = new EchoServiceImpl(); EchoServiceVi port = service.getEchoServiceSoapPortrpcEnc(); String param = "Hello World!"; String result = port.echoString(param); System.out.println("call to [.echoString]:"+param); System.out.println("result [.echoString]:"+result); } } |
From the example below, you can see that the complex structures used in the Web services are represented as simple beans. The proxy generator also supports deserialization of Web service faults:

package echoservice; import echoservice.types.p2.StructA; import java.rmi.RemoteException;
public class Tester { public static void callStruct(EchoServiceVi port) throws RemoteException { StructA a = new StructA(); a.setFirstName("Harry"); a.setSecondName("Potter"); a.setId(15); a.setIsGood(true); port.echoStructA(a); } public static void callException(EchoServiceVi port) throws RemoteException { StructA a = new StructA(); a.setFirstName("Harry"); a.setSecondName("Potter"); a.setId(15); a.setIsGood(true); try { port.throwCheckedException(a); } catch (MyException e) { System.out.println(e.getContent().getFirstName()); System.out.println(e.getContent().getSecondName()); } } public static void main(String[] args) throws Exception { EchoService service = new EchoServiceImpl(); EchoServiceVi port = service.getEchoServiceSoapPortrpcEnc(); String param = "Hello World!"; String result = port.echoString(param); System.out.println("call to [.echoString]:"+param); System.out.println("result [.echoString]:"+result); callStruct(port); callException(port); } } |
When using a deployable Web service client, it is bound in the JNDI under a specific context name. You have to replace the service implementation instantiation with a lookup in the JNDI. If you assumed that the service context route is java:comp/env/EchoService, then the lookup code must appear as follows:

//EchoService service = new EchoServiceImpl(); Context ctx = new InitialContext(); EchoService service = (EchoService) ctx.lookup("java:comp/env/EchoService"); //EchoServiceVi port = service.getEchoServiceSoapPortrpcEnc(); EchoServiceVi port = (EchoServiceVi) service.getLogicalPort(EchoServiceVi.class); String param = "Hello World!"; String result = port.echoString(param); |
When you are in a server environment, you can use container-managed port access. In this way, you leave it to the container to decide which implementation to return, and you do not have to pass the logical port name.
Typically, with Web services there are scenarios where additional application functions are required. Some Web services require a secure connection; others require session maintenance through the calls. Often we use Web services behind a firewall. An HTTP proxy also needs to be set. Typically, this must be implemented in an extensible manner and there must also be some way for the Web service provider to give hints to the client. Typically for SAP, this is done using the SAP WSDL. This is an extended WSDL in which application preferences are described using extensions called “features”. They are represented as extension elements in SOAP and describe the Web service requirements or restrictions. Their description and semantics are public, that is, available for non-SAP users so that they can be implemented in a vendor-specific manner. For example, a Web service that requires basic authentication may be used through generic WSDL by a non-SAP user. Knowing that this authentication is required, the user uses vendor-specific tools to implement it and call this Web service. For SAP users this task is easier, since the SAP WSDL Proxy Generator recognizes extended SAP WSDL, and extracts feature requirements and configures itself so that it can support SAP WSDL. No coding is required to add the support of these features. The feature configuration is stored in the lports.xml file and, when deployed, it is passed to the container. The container itself accepts these configurations and supports them.
The feature implementation and configuration is done using Protocols, which are classes that can intercept Web service call messages and configurations during Web service calls. Even when a Web service feature is used, there must be some way of configuring it. Protocols are provided by the environment developers and we should not worry about their structure. As users we need to know which protocol implements which specific feature, and what configuration interface they provide us with. For example, the SOAP headers support is implemented using the SOAP protocol.
See also:
