cancel
Showing results for 
Search instead for 
Did you mean: 

invoking a web service

Former Member
0 Kudos

Hello All,

I am trying to invoke a web service hosted on webMethods (our R/3 being an older version, can't expose function modules as web services). I am able to generate Java proxies from the wsdl provided by webMethods. But, I found by studying the generated Java proxies/stubs that its required to send both input (import) and output (export) parameters to invoke the function module.

To give you an example, lets say, my function module takes 3 input parameters and returns 120 output parameters. So, to invoke this function, I thought I just need 3 parameters to be supplied to make a call like invokeXYZ(param1, param2, param3). But, when I looked at the generated code, I saw that I need to supply a total of 3 + 120 parameters to invoke the web service. 120 of them are empty objects of type output parameter.

I think either SAP isn't generating the proxy classes correctly (You don't want to supply 120 arguments to make a call) or I am doing something wrong.

Any suggestions/comments appreciated.

Thanks,

Kiran

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Kiran,

It seems that there is some misunderstanding.

If WSDL is pulbically accessible please provide a link, otherwise post WSDL source -- this will help to answer you.

VS

Former Member
0 Kudos

Valery,

Here's the wsdl. I removed most of the out parameters for brevity.

<?xml version="1.0" encoding="UTF-8"?>
	<wsdl:definitions name="Neal_test_package_Handlers" targetNamespace="http://hpgena2d/"
			xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
			xmlns:xsd="http://www.w3.org/2001/XMLSchema"
			xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
			xmlns:tns="http://hpgena2d/"
			xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
			xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
	<wsdl:types>
        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://localhost/Neal_test_package/Handlers/invokeZ_CCS_CUST_INFO" xmlns:tns="http://localhost/Neal_test_package/Handlers/invokeZ_CCS_CUST_INFO">
          <xsd:complexType name="__in">
            <xsd:sequence>
              <xsd:element name="wmAlias" nillable="true" type="xsd:string"/>
              <xsd:element name="SEL_CONTRACT_ACCOUNT" nillable="true" type="xsd:string" minOccurs="0"/>
              <xsd:element name="SEL_LEGACY_ACCOUNT" nillable="true" type="xsd:string" minOccurs="0"/>
            </xsd:sequence>
          </xsd:complexType>
          <xsd:complexType name="__out">
            <xsd:sequence>
              <xsd:element name="ACCOUNT_BALANCE" nillable="true" type="xsd:string"/>
              <xsd:element name="ACCOUNT_NAME" nillable="true" type="xsd:string"/>
              <xsd:element name="ACCOUNT_STATUS" nillable="true" type="xsd:string"/>
              <xsd:element name="ACCOUNT_STATUS_DESC" nillable="true" type="xsd:string"/>
              <xsd:element name="APP_CYCLING" nillable="true" type="xsd:string"/>
 .....
.....
            </xsd:sequence>
          </xsd:complexType>
        </xsd:schema>

	</wsdl:types>
	
	<wsdl:message name="invokeZ_CCS_CUST_INFOInput">
		<wsdl:part name="wmAlias" type="xsd:string"/>
		<wsdl:part name="SEL_CONTRACT_ACCOUNT" type="xsd:string"/>
		<wsdl:part name="SEL_LEGACY_ACCOUNT" type="xsd:string"/>
	</wsdl:message>
	
	<wsdl:message name="invokeZ_CCS_CUST_INFOOutput">
		<wsdl:part name="ACCOUNT_BALANCE" type="xsd:string"/>
		<wsdl:part name="ACCOUNT_NAME" type="xsd:string"/>
		<wsdl:part name="ACCOUNT_STATUS" type="xsd:string"/>
		<wsdl:part name="ACCOUNT_STATUS_DESC" type="xsd:string"/>
....
....
	</wsdl:message>
	<wsdl:portType name="Neal_test_package_HandlersPortType">
		<wsdl:operation name="invokeZ_CCS_CUST_INFO">
			<wsdl:input message="tns:invokeZ_CCS_CUST_INFOInput"/>
			<wsdl:output message="tns:invokeZ_CCS_CUST_INFOOutput"/>
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="Neal_test_package_HandlersBinding" type="tns:Neal_test_package_HandlersPortType">
		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
		<wsdl:operation name="invokeZ_CCS_CUST_INFO">
			<soap:operation soapAction=""/>
			<wsdl:input>
				<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://hpgena2d/Neal_test_package.Handlers" use="encoded"/>
			</wsdl:input>
			<wsdl:output>
				<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://hpgena2d/Neal_test_package.Handlers" use="encoded"/>
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="Neal_test_package_HandlersService">
		<wsdl:port name="Neal_test_package_HandlersPort0" binding="tns:Neal_test_package_HandlersBinding">
			<soap:address location="https://hpgena2d:5555/soap/FEWSController"/>
		</wsdl:port>
	</wsdl:service>
	</wsdl:definitions>

Thanks for your time,

Kiran

Former Member
0 Kudos

Kiran,

Please post <b>complete</b> WSDL or submit it to <b>vsilaev AT gmail DOT com</b> so I will able to import it as WebService model and talk with you about concrete things.

VS

Former Member
0 Kudos

Kiran,

This very unusual WSDL, however it is valid. And SAP plugins generate correct proxy classes.

So you have 3 IN parameters, and 120 IN-OUT parameters. You have to assign <b>new StringHolder</b> to all of these 120 parameters (otherwise you got NullPointerException on execute).

Here is the short way (shorter then 120 assignments


import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.InvocationTargetException;
....
final Method[] methods =
  Request_NealTestPackageHandlersPortType_invokeZ_CCS_CUST_INFO
    .class.getDeclaredMethods();

final Object[] args = {null};
try
{
  for (int i = 0, c = methods.length; i < c; i++)
  {
    final Method m = methods[ i ];
				
    if ( !m.getName().startsWith("set") ) continue;

    final int flags = m.getModifiers();
    if ( !Modifier.isPublic(flags) || Modifier.isStatic(flags) ) continue;
				
    final Class[] types = m.getParameterTypes();
    if ( null == types || types.length != 1 || types[0] != StringHolder.class ) continue;
				
    /* Now we now that this is method that assigns IN_OUT parameter */
    /* "request" below is your WebService request instance, type Request_.... */
    args[0] = new StringHolder();
    m.invoke( request, args );
  }
}
catch (final IllegalAccessException ex) { throw new RuntimeException(ex); }		
catch (final IllegalArgumentException ex) { throw new RuntimeException(ex); }		
catch (final InvocationTargetException ex) { throw new RuntimeException(ex.getTargetException()); }

Valery Silaev

EPAM Systems

http://www.NetWeaverTeam.com

Message was edited by: Valery Silaev

Former Member
0 Kudos

Valery,

Thanks a lot. Can you please tell me whats unusual about this web service? I can carry that to my webMethods developer to help him configure the web service better.

Thanks,

Kiran

Former Member
0 Kudos

Kiran,

I'm not an WSDL profy, but you may (both compare this service with any WS with RPC-style (Remote Procedure Call) encoding, take a look at number of services at xmethods.com

Just one hint. What grab my attention is that inline schema defined in WSDL is <b>never used</b>. So _in and _out types are declared, SAP plugins create corresponding classes, but they are never used. Pay attention to this.

Valery Silaev

EPAM Systems

http://www.NetWeaverTeam.com

Former Member
0 Kudos

Valery,

I agree about the __in and __out types. I am talking to our web service developer about this. In the code snippet you sent, I don't find "<b>Request_NealTestPackageHandlersPortType_invokeZ_CCS_CUST_INFO</b>" class generated in my project.

These are the classes/interfaces generated in NWDS sp13

1.class NealTestPackageHandlersBindingStub

2.class NealTestPackageHandlersServiceImpl

3.interface NealTestPackageHandlersService

4.interface NealTestPackageHandlersPortType

and ofcourse the __in and __out which aren't used anywhere.

Thanks,

Kiran

Former Member
0 Kudos

Kiran,

Actually, it depends what type of WS import you are using. I used WS model generator for WebDynpro. If you are using WS proxy generator the classes could be different but idea is the same. Just select class that has getter/setters with StringHolder type. AFAIK, *Stub.

VS

Answers (0)