Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   ASP .Net Web Services (http://www.velocityreviews.com/forums/f64-asp-net-web-services.html)
-   -   How do you transparently implement the same web service (WSDL) with java axis and .NET ? (http://www.velocityreviews.com/forums/t784984-how-do-you-transparently-implement-the-same-web-service-wsdl-with-java-axis-and-net.html)

tomjbr.10216233@bloglines.com 05-10-2005 12:18 AM

How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
When I have tried to generate java and C# servers/clients from the same
WSDL as described further below, these are the results I have been able
to achieve:
OK: C# proxy invokes C# service
OK: C# proxy invokes Java service
OK: Java proxy invokes Java service
NOT OK: Java proxy invokes C# service

When I try to invoke a C# web service with a java axis client I get the
error message:
"Server did not recognize the value of HTTP Header SOAPAction: ."

I have been struggling with implementing web services with java and
..NET that are supporting the same WSDL and to be able to reuse client
code that are using these services.
To be more specific, I would like to implement the very same (from a
WSDL point of view) web service with both Java Axis and C# (as an
ASP.NET web services).
For both of these two servers, I would then like to create one client
with Java Axis and one client with C# that can reuse these two services
through polymorphistic invocations of a common interface.

My key question is:

Where can I find code examples that describe the best way to create
java axis clients/servers and .NET web services clients/servers which
can communicate with each other in a transparent way ???

I mean, since the location transparency is often described as a key
issue in a SOA implemented with web services then this should be a very
common problem ?
Anyone who is using UDDI to look up implementations of a certain WSDL
that is pointed to from a tModel in an UDDI server should have run into
this kind of problem, when you want to dynamically bind to different
implementations of the same WSDL interface...
(though, maybe not too many people are actually using UDDI in reality,
and maybe UDDI still essentially just occurrs on nice power point
slides showing what you can do with web services...)

This is the kind of approach I have tried:

1. Define a normal java interface

2. Generate a WSDL file from that java interface by using the java axis
tool "org.apache.axis.wsdl.Java2WSDL"

3. Generate java client and service code from the WSDL file by using
the java axis tool "org.apache.axis.wsdl.WSDL2Java" (including the
interface "MyServiceInterface" and the class "MyServiceLocator" in the
code below and also including a skeleton server class
"MyServiceSoapBindingImpl" where I then put the implementation)

4. Generate an abstract C# class from the WSDL file by using the MS
tool "wsdl.exe"

5. Create a web service "service.asmx" (with Visual Studio.NET 20003)
and manually change it so it inherits from the class generated in the
previous step 4, instead of the default inheritance from
"System.Web.Services.WebService".
In this subclass (Service1.asmx.cs) I then implement the abstract
methods and tag them with "[WebMethod]"

6. Manually define a C# interface ( "IMyWebServiceInterface" in the
code further below with the C# web service methods)

7. Generate a C# client proxy class for the java axis web service
(which I of course deployed after step 3 above) by adding a web
reference in VS.NET 2003 and then pointing to the WSDL file.

8. Manually edit the proxy class generated in step 7 above (the class
that inherits from "SoapHttpClientProtocol") so that it also implements
the interface I created in step 6 above.

9. Repeat step 7 och 8 above to create a C# proxy class that can use
the C# web service through that same C# interface created in step 6.

The only thing that I can not make work is the java axis client to
invoke the C# web service.
When I do it, I get the following SOAP faultstring message:
"Server did not recognize the value of HTTP Header SOAPAction: ."

I believe that the reason for the trouble is that the ASP.NET web
service does not generate exactly the same WSDL as the original WSDL.
In other words, when I generated the abstract C# class from the WSDL
file by using the MS tool wsdl.exe and then created a "service.asmx"
that I then let inherit from this generated class, then when I run
"service.asmx?wsdl" in a web browser then it is not exactly the same
WSDL as the original.

So the question is what should I do instead of the stuff I described
above, when I want to create java axis and .NET clients/servers that
can communicate with each other ???

Below I provide some code, just in case it would be unclear what I am
trying to do.

Here is the kind of end result code with a Java Axis client that I
would like to be able to use:

String webserviceURLs[] = new String[]{
"http://www.csharpedomain.com/service.asmx",
"http://www.javadomain.com/axis/services/JavaWebService"
};
MyServiceInterface myService;
MyServiceLocator myServiceLocator = new MyServiceLocator();
for (int i = 0; i < webserviceURLs.length; i++) {
myService = myServiceLocator.getMyService(webserviceURLs[i]);
myService.myMethod(); // the polymorphistic invocation
}

Here is the kind of end result code with a C# client that I was able to
use:

public void someMethod()
{
IMyWebServiceInterface[] webServiceInterfaces = getWebServiceProxys();
foreach(IMyWebServiceInterface webServiceProxy in
webServiceInterfaces)
{
webServiceProxy.getServiceBeskrivning(); // the polymorphistic
invocation
}
}

private IMyWebServiceInterface[] getWebServiceProxys()
{
IMyWebServiceInterface[] webServiceInterfaces = new
IMyWebServiceInterface[2];
webServiceInterfaces[0] = new localhost_java_MyService();
webServiceInterfaces[1] = new localhost_csharpe_MyService();
return webServiceInterfaces;
}

However, I would prefer if there was some easier way to create a C#
client that transparently (through polymorphism) can invoke the
services than to manually create the interface "IMyWebServiceInterface"
and instantiate the concrete classes as above, i.e. I would prefer to
do something that is more like the axis client above where you can
provide url strings to the implementations of the web services that
supports the same WSDL.

/ Tom


Chad Z. Hower aka Kudzu 05-10-2005 08:22 AM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
"tomjbr.10216233@bloglines.com" <tomjbr.10216233@bloglines.com> wrote in
news:1115684293.231280.162480@z14g2000cwz.googlegr oups.com:
> I have been struggling with implementing web services with java and
> NET that are supporting the same WSDL and to be able to reuse client
> code that are using these services.


I think this may prove difficult since ASP.NET webservices focus on
generating the WSDL for you based on C#/VB interfaces.



--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Blog: http://blogs.atozed.com/kudzu

tomjbr.10216233@bloglines.com 05-10-2005 12:10 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
"Chad Z. Hower aka Kudzu" wrote:
>I think this may prove difficult since ASP.NET webservices focus on
>generating the WSDL for you based on C#/VB interfaces.


Well, it is possible to use a C# interface after it has been added
manually to the generated proxies.
I did illustrate it above, and by the way I got the idea from the "Web
Service Interface pattern" in the book ".NET patterns" from 2003 by
Christian Thilmany. Though, I am not sure whether that book was written
before or after .NET 1.1 or Visual Studio.NET 2003. Since the manual
process is not optimal I was hoping that there would be a better way,
but maybe there is not.

Anyway, the main problem was how to let the java axis client invoke a
C# web service, in a transparent way, i.e. I want to let the java
client use an interface that can be used for dynamically invoking
either a java web service or a C# web service.

I can not believe this should be so difficult, so let us then talk a
little about what UDDI is supposed to be able to do for us.
If you are using UDDI, you can use the "find_binding" message with a
tModelKey (that for example can be used as a key to a certain WSDL
interface) as a parameter.
The resulting return message of "find_binding" is a list of
"bindingTemplate" structures where each such template contains an
"accesssPoint" element which contains an URL to a web service which
supports the certain WSDL.

Now then, when I from an UDDI server have got this list of URL's to web
services supporting the requested WSDL interface, how can I then
dynamically connect to these web services ???
I can indeed do it in runtime with many java axis web services, but one
important aspect of a SOA (i.e. web services) is also the
implementation transparency, i.e. it should be possible to connect to
..NET for example (if I would be interested in java only, then I could
use RMI instead)

/ Tom


Chad Z. Hower aka Kudzu 05-10-2005 03:46 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
"tomjbr.10216233@bloglines.com" <tomjbr.10216233@bloglines.com> wrote in
news:1115727053.799235.149480@f14g2000cwb.googlegr oups.com:
>>I think this may prove difficult since ASP.NET webservices focus on
>>generating the WSDL for you based on C#/VB interfaces.

>
> Well, it is possible to use a C# interface after it has been added
> manually to the generated proxies.


I didnt say it was impossible, I said it would prove difficult.

> Anyway, the main problem was how to let the java axis client invoke a
> C# web service, in a transparent way, i.e. I want to let the java
> client use an interface that can be used for dynamically invoking
> either a java web service or a C# web service.


I would ask this on a Java group as the problem appears to be with Java
interpreting the WSDL. Ive not consumed C# web services from Java, but I
have consumed them without trouble in Delphi (Win32 and .NET).

> Now then, when I from an UDDI server have got this list of URL's to web
> services supporting the requested WSDL interface, how can I then
> dynamically connect to these web services ???
> I can indeed do it in runtime with many java axis web services, but one
> important aspect of a SOA (i.e. web services) is also the
> implementation transparency, i.e. it should be possible to connect to
> NET for example (if I would be interested in java only, then I could
> use RMI instead)


If you know what type of service you are looking for with UDDI, you could
pregenerate each of the interface types before as well no?


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Blog: http://blogs.atozed.com/kudzu

Ajay Choudhary 05-10-2005 06:10 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
You will find useful information at -

http://msdn.microsoft.com/library/de...ntegration.asp

<tomjbr.10216233@bloglines.com> wrote in message
news:1115684293.231280.162480@z14g2000cwz.googlegr oups.com...
> When I have tried to generate java and C# servers/clients from the same
> WSDL as described further below, these are the results I have been able
> to achieve:
> OK: C# proxy invokes C# service
> OK: C# proxy invokes Java service
> OK: Java proxy invokes Java service
> NOT OK: Java proxy invokes C# service
>
> When I try to invoke a C# web service with a java axis client I get the
> error message:
> "Server did not recognize the value of HTTP Header SOAPAction: ."
>
> I have been struggling with implementing web services with java and
> .NET that are supporting the same WSDL and to be able to reuse client
> code that are using these services.
> To be more specific, I would like to implement the very same (from a
> WSDL point of view) web service with both Java Axis and C# (as an
> ASP.NET web services).
> For both of these two servers, I would then like to create one client
> with Java Axis and one client with C# that can reuse these two services
> through polymorphistic invocations of a common interface.
>
> My key question is:
>
> Where can I find code examples that describe the best way to create
> java axis clients/servers and .NET web services clients/servers which
> can communicate with each other in a transparent way ???
>
> I mean, since the location transparency is often described as a key
> issue in a SOA implemented with web services then this should be a very
> common problem ?
> Anyone who is using UDDI to look up implementations of a certain WSDL
> that is pointed to from a tModel in an UDDI server should have run into
> this kind of problem, when you want to dynamically bind to different
> implementations of the same WSDL interface...
> (though, maybe not too many people are actually using UDDI in reality,
> and maybe UDDI still essentially just occurrs on nice power point
> slides showing what you can do with web services...)
>
> This is the kind of approach I have tried:
>
> 1. Define a normal java interface
>
> 2. Generate a WSDL file from that java interface by using the java axis
> tool "org.apache.axis.wsdl.Java2WSDL"
>
> 3. Generate java client and service code from the WSDL file by using
> the java axis tool "org.apache.axis.wsdl.WSDL2Java" (including the
> interface "MyServiceInterface" and the class "MyServiceLocator" in the
> code below and also including a skeleton server class
> "MyServiceSoapBindingImpl" where I then put the implementation)
>
> 4. Generate an abstract C# class from the WSDL file by using the MS
> tool "wsdl.exe"
>
> 5. Create a web service "service.asmx" (with Visual Studio.NET 20003)
> and manually change it so it inherits from the class generated in the
> previous step 4, instead of the default inheritance from
> "System.Web.Services.WebService".
> In this subclass (Service1.asmx.cs) I then implement the abstract
> methods and tag them with "[WebMethod]"
>
> 6. Manually define a C# interface ( "IMyWebServiceInterface" in the
> code further below with the C# web service methods)
>
> 7. Generate a C# client proxy class for the java axis web service
> (which I of course deployed after step 3 above) by adding a web
> reference in VS.NET 2003 and then pointing to the WSDL file.
>
> 8. Manually edit the proxy class generated in step 7 above (the class
> that inherits from "SoapHttpClientProtocol") so that it also implements
> the interface I created in step 6 above.
>
> 9. Repeat step 7 och 8 above to create a C# proxy class that can use
> the C# web service through that same C# interface created in step 6.
>
> The only thing that I can not make work is the java axis client to
> invoke the C# web service.
> When I do it, I get the following SOAP faultstring message:
> "Server did not recognize the value of HTTP Header SOAPAction: ."
>
> I believe that the reason for the trouble is that the ASP.NET web
> service does not generate exactly the same WSDL as the original WSDL.
> In other words, when I generated the abstract C# class from the WSDL
> file by using the MS tool wsdl.exe and then created a "service.asmx"
> that I then let inherit from this generated class, then when I run
> "service.asmx?wsdl" in a web browser then it is not exactly the same
> WSDL as the original.
>
> So the question is what should I do instead of the stuff I described
> above, when I want to create java axis and .NET clients/servers that
> can communicate with each other ???
>
> Below I provide some code, just in case it would be unclear what I am
> trying to do.
>
> Here is the kind of end result code with a Java Axis client that I
> would like to be able to use:
>
> String webserviceURLs[] = new String[]{
> "http://www.csharpedomain.com/service.asmx",
> "http://www.javadomain.com/axis/services/JavaWebService"
> };
> MyServiceInterface myService;
> MyServiceLocator myServiceLocator = new MyServiceLocator();
> for (int i = 0; i < webserviceURLs.length; i++) {
> myService = myServiceLocator.getMyService(webserviceURLs[i]);
> myService.myMethod(); // the polymorphistic invocation
> }
>
> Here is the kind of end result code with a C# client that I was able to
> use:
>
> public void someMethod()
> {
> IMyWebServiceInterface[] webServiceInterfaces = getWebServiceProxys();
> foreach(IMyWebServiceInterface webServiceProxy in
> webServiceInterfaces)
> {
> webServiceProxy.getServiceBeskrivning(); // the polymorphistic
> invocation
> }
> }
>
> private IMyWebServiceInterface[] getWebServiceProxys()
> {
> IMyWebServiceInterface[] webServiceInterfaces = new
> IMyWebServiceInterface[2];
> webServiceInterfaces[0] = new localhost_java_MyService();
> webServiceInterfaces[1] = new localhost_csharpe_MyService();
> return webServiceInterfaces;
> }
>
> However, I would prefer if there was some easier way to create a C#
> client that transparently (through polymorphism) can invoke the
> services than to manually create the interface "IMyWebServiceInterface"
> and instantiate the concrete classes as above, i.e. I would prefer to
> do something that is more like the axis client above where you can
> provide url strings to the implementations of the web services that
> supports the same WSDL.
>
> / Tom
>




tomjbr.10216233@bloglines.com 05-10-2005 08:54 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
Now I have documented all generated WSDL files and also all SOAP
messages, and have attached them below in this message.

The problem seems to be that when you take an original WSDL file and
generate Java Axis code and C# ASP.NET code,
then the Axis and ASP.NET will return different WSDL files than the
original WSDL file.

Axis generates
<wsdlsoap:operation soapAction=""/>
in the WSDL file, while Microsoft does not, but instead will give the
SOAP fault message "Server did not recognize the value of HTTP Header
SOAPAction: ."
However, that is not the only difference, but there are other
significant differences in the generated WSDL files, which you can see
futher down in this message.

I guess the key question here is one of the following:

(1) What am I doing wrong below in the commands I am using for the
code/WSDL generation ???

(2) Which tool is not following the WSDL standard ???
(The Axis team's "Java2WSDL" or "WSDL2Java", or Microsoft's "wsdl.exe"
or ASP.NET's runtime that returns a different WSDL than the original)

The rest of this message illustrates the procedure I have followed for
code generation, including all resulting WSDL files and SOAP messages.

- - - - - - - - - - -

First I manually create a java interface:

package com.myPackage;
public interface MyService {
String getMyString();
}

Then I generate a WSDL file from the above interface with this command:

java -cp .;%AXISCLASSPATH% org.apache.axis.wsdl.Java2WSDL -o
myservice.wsdl -l"http://localhost:8083/axis/services/MyService"
com.myPackage.MyService

I am using the latest Axis 1.2 final release version from the 3rd of
may 2005.

This is the WSDL file generated by the above command:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://myPackage.com"
xmlns:impl="http://myPackage.com" xmlns:intf="http://myPackage.com"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<!--WSDL created by Apache Axis version: 1.2
Built on May 03, 2005 (02:20:24 EDT)-->

<wsdl:message name="getMyStringRequest">

</wsdl:message>

<wsdl:message name="getMyStringResponse">

<wsdl:part name="getMyStringReturn" type="soapenc:string"/>

</wsdl:message>

<wsdl:portType name="MyService">

<wsdl:operation name="getMyString">

<wsdl:input name="getMyStringRequest"
message="impl:getMyStringRequest"/>

<wsdl:output name="getMyStringResponse"
message="impl:getMyStringResponse"/>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="MyServiceSoapBinding" type="impl:MyService">

<wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="getMyString">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="getMyStringRequest">

<wsdlsoap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://myPackage.com"/>

</wsdl:input>

<wsdl:output name="getMyStringResponse">

<wsdlsoap:body use="encoded"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://myPackage.com"/>

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="MyServiceService">

<wsdl:port name="MyService" binding="impl:MyServiceSoapBinding">

<wsdlsoap:address
location="http://localhost:8083/axis/services/MyService"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

Then I generate the java code (client proxy and server skeleton
implementation for axis):
java -cp .;%AXISCLASSPATH% org.apache.axis.wsdl.WSDL2Java -p
com.myGeneratedPackage --server-side --skeletonDeploy true
myservice.wsdl

I implement the generated class "MyServiceSoapBindingImpl" like this:

public class MyServiceSoapBindingImpl implements
com.myGeneratedPackage.MyService_PortType{
public java.lang.String getMyString() throws
java.rmi.RemoteException {
return "This is a Java Axis implementation";
}
}
(the only thing I changed in the class above was the return value,
which axis generated to null)

Then I deploy the axis service with this command:

java -cp .;%AXISCLASSPATH% org.apache.axis.client.AdminClient
-lhttp://localhost:8083/axis/services/AdminService
com\myGeneratedPackage\deploy.wsdd

Then I can access the web service at this URL:
http://localhost:8083/axis/services/MyService

And this URL will show me a WSDL file generated from the Java Axis Web
Service:
http://localhost:8083/axis/services/MyService?WSDL
and it will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://myPackage.com"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://myPackage.com" xmlns:intf="http://myPackage.com"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.2
Built on May 03, 2005 (02:20:24 EDT)-->

<wsdl:message name="getMyStringRequest">

</wsdl:message>

<wsdl:message name="getMyStringResponse">

<wsdl:part name="getMyStringReturn" type="soapenc:string"/>

</wsdl:message>

<wsdl:portType name="MyService">

<wsdl:operation name="getMyString">

<wsdl:input message="impl:getMyStringRequest"
name="getMyStringRequest"/>

<wsdl:output message="impl:getMyStringResponse"
name="getMyStringResponse"/>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="MyServiceSoapBinding" type="impl:MyService">

<wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="getMyString">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="getMyStringRequest">

<wsdlsoap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://myPackage.com" use="encoded"/>

</wsdl:input>

<wsdl:output name="getMyStringResponse">

<wsdlsoap:body
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://myPackage.com" use="encoded"/>

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="MyServiceService">

<wsdl:port binding="impl:MyServiceSoapBinding" name="MyService">

<wsdlsoap:address
location="http://localhost:8083/axis/services/MyService"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

As far as I can see, the only difference between the above WSDL
generated from the Axis Web service and the original WSDL futher up is
that the orders of the attributes are sometimes different.

Then I set up the axis utility TCPMonitor so that port 8155 redirects
to port 8083 and implemented a client like this:

import com.myGeneratedPackage.MyServiceServiceLocator;
import com.myGeneratedPackage.MyService_PortType;
public class MyServiceClient {
public static void main(String[] args) throws Exception {
MyServiceServiceLocator myServiceLocator = new
MyServiceServiceLocator();
MyService_PortType myService = myServiceLocator.getMyService(
new URL("http://localhost:8155/axis/services/MyService")
);
String myString = myService.getMyString();
System.out.println("Result: " + myString);
}
}

(both the class "MyServiceServiceLocator" and the interface
"MyService_PortType" above were generated above further up by the axis
tool WSDL2Java)

When I run the code above it works fine, and when I look at the
TCPMonitor output, here is the SOAP request:

POST /axis/services/MyService HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related,
text/*
User-Agent: Axis/1.2
Host: 127.0.0.1
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 378

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getMyString
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://myPackage.com"/>
</soapenv:Body>
</soapenv:Envelope>

and here is the SOAP response:

HTTP/1.1 200 OK
Content-Type: text/xml;charset=utf-8
Date: Tue, 10 May 2005 19:12:13 GMT
Server: Apache-Coyote/1.1
Connection: close

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getMyStringResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://myPackage.com">
<getMyStringReturn xsi:type="soapenc:string"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">This is a
Java Axis implementation</getMyStringReturn>
</ns1:getMyStringResponse>
</soapenv:Body>
</soapenv:Envelope>

OK, so far I have only done a java only implementation, i.e. I have
made a web service client which can invoke a web service, where both
the client proxy and the server skeleton has been generated with java
axis.

Now, it is time to create a web service with C# and ASP.NET, using the
same WSDL interface (myservice.wsdl) as above.

I now use the wsdl.exe tool like this:

wsdl.exe myservice.wsdl /server /namespace:com.myGeneratedPackage
/out:MyService.cs

The above command generated the following "MyService.cs" asbtract
class:

namespace com.myGeneratedPackage {
using System.Diagnostics;
using System.Xml.Serialization;
using System;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Web.Services;
/// <remarks/>

[System.Web.Services.WebServiceBindingAttribute(Nam e="MyServiceSoapBinding",
Namespace="http://myPackage.com")]
public abstract class MyServiceService :
System.Web.Services.WebService {
/// <remarks/>
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapRpcMethodAttribu te("",
RequestNamespace="http://myPackage.com",
ResponseNamespace="http://myPackage.com")]
[return:
System.Xml.Serialization.SoapElementAttribute("get MyStringReturn")]
public abstract string getMyString();
}
}

Now I create a web service "MyConcreteService.asmx" with Visual
Studio.NET 2003.
Then I go into the code for "MyConcreteService.asmx.cs" and implement
(override) the abstract class and change the inheritance to make it
inherit from MyServiceService instead of inheriting from
System.Web.Services.WebService.
Also, I add the [WebMethod] attribute.
Now this class looks like this:

public class MyConcreteService : MyServiceService
{
public MyConcreteService()
{
//CODEGEN: This call is required by the ASP.NET Web Services
Designer
InitializeComponent();
}
[WebMethod]
public override string getMyString()
{
return "This is a C# ASP.NET implementation";
}

#region Component Designer generated code

//Required by the Web Services Designer
private IContainer components = null;

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}

#endregion
}

Now I can access the web service at this URL:
http://localhost/WebServices/MyConcreteService.asmx

And this URL will show me a WSDL file generated from IIS/ASP.NET:
http://localhost/WebServices/MyConcr...vice.asmx?WSDL
and it will look like this:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://tempuri.org/"
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
targetNamespace="http://tempuri.org/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<s:schema elementFormDefault="qualified"
targetNamespace="http://tempuri.org/">
<s:element name="getMyString">
<s:complexType />
</s:element>
<s:element name="getMyStringResponse">
<s:complexType>
<s:sequence>

<s:element minOccurs="0" maxOccurs="1"
name="getMyStringResult" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="getMyStringSoapIn">
<wsdl:part name="parameters" element="tns:getMyString" />
</wsdl:message>

<wsdl:message name="getMyStringSoapOut">
<wsdl:part name="parameters" element="tns:getMyStringResponse" />
</wsdl:message>
<wsdl:portType name="MyConcreteServiceSoap">
<wsdl:operation name="getMyString">
<wsdl:input message="tns:getMyStringSoapIn" />
<wsdl:output message="tns:getMyStringSoapOut" />
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="MyConcreteServiceSoap"
type="tns:MyConcreteServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<wsdl:operation name="getMyString">
<soap:operation soapAction="http://tempuri.org/getMyString"
style="document" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />

</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MyConcreteService">
<documentation xmlns="http://schemas.xmlsoap.org/wsdl/" />
<wsdl:port name="MyConcreteServiceSoap"
binding="tns:MyConcreteServiceSoap">
<soap:address
location="http://localhost/WebServices/MyConcreteService.asmx" />
</wsdl:port>
</wsdl:service>

</wsdl:definitions>

Obviously the above WSDL is very different from the original one, which
did not even have any wsdl:types element.
Another big difference is the targetNamespace="http://tempuri.org/"
versus the original targetNamespace="http://myPackage.com"
But maybe the most significant difference (considering the below SOAP
error message) is the fact that the following element:
<wsdlsoap:operation soapAction=""/>
does not occurr in the ASP.NET generated WSDL, which it did in the
original WSDL file above that I used for all code generation.

For the sake of completness I will nelow continue with illustrating the
SOAP requests and responses when I try to execute this .NET service
from this java axis proxy:

MyServiceServiceLocator myServiceLocator = new
MyServiceServiceLocator();
MyService_PortType myService = myServiceLocator.getMyService(
new
URL("http://localhost:8156/WebServices/MyConcreteService.asmx?WSDL")
);
String myString = myService.getMyString();
System.out.println("Result: " + myString);
(before the execution of this code above, I have set up redirection of
port 8156 to port 80 in TCPMonitor)

The SOAP request:

POST /WebServices/MyConcreteService.asmx?WSDL HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml, application/dime, multipart/related,
text/*
User-Agent: Axis/1.2
Host: 127.0.0.1
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 378

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:getMyString
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns1="http://myPackage.com"/>
</soapenv:Body>
</soapenv:Envelope>


The SOAP response:

HTTP/1.1 500 Internal Server Error.
Server: Microsoft-IIS/5.1
Date: Tue, 10 May 2005 19:57:59 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 453

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Server did not recognize the value of HTTP
Header SOAPAction: .</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>

/ Tom


tomjbr.10216233@bloglines.com 05-10-2005 09:01 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
Well, thank you but I do not think it is too useful these days.
That page is from October 2003, and is just at the bottom mentioning
"Axis, also known as Apache SOAP 3.0", and the page describes Apache
SOAP which did not even support WSDL.

/ Tom


tomjbr.10216233@bloglines.com 05-10-2005 09:17 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
>If you know what type of service you are looking for with UDDI,
>you could pregenerate each of the interface types before as well no?


Well, yes I am generating everything.
First I generate the WSDL file from a java interface, and then I
generate client proxies and server skeletons (in both java and C#) from
the WSDL file.

But I am not quite sure what your point was here.
Maybe you mean that I can look for one particular service, and then
find a WSDL file and generate a proxy for that service. Then I can find
another kind of service with another WSDL file and generate a proxy for
that service.
Sure I could do that, but that is not what I want to do.

The thing I want to do is to be able to invoke multiple web services
which are supporting the same WSDL interface.

And I want to do it with polymorphism, so I can do it dynamically when
I in runtime find a new URL supporting the same WSDL interface, without
having to generate a new class each time.

And my point of doing the UDDI comparison was that just if you can not
even do this stuff with hardcoding some URL strings (which I have
tried) , then how are you supposed to implement software that are using
an UDDI server to dynamically find and bind to URL's that support a
certain WSDL interface that has been registered in an UDDI tModel
structure.

/ Tom


tomjbr.10216233@bloglines.com 05-10-2005 10:19 PM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
I now think the problem may have something to do with the Java2WSDL
argument "-A, --soapAction <argument>" which I have not been using.
When I run Java2WSDL it generates this:
<wsdlsoap:operation soapAction=""/>
and .NET will then be complaining about "Server did not recognize the
value of HTTP Header SOAPAction: ."

Though, I do not really understand exactly what I should do about it.
As far as I understand, the soapAction attribute should be an URL, but
on the other hand it does not make any sense to me to specify a URL in
an interface that will be used for generating different implementations
that will have different URL's.

So maybe I am misunderstanding something conceptually essential about
why a SOAPAction (URL?) should be in an interface ?

/ Tom


Chad Z. Hower aka Kudzu 05-11-2005 05:41 AM

Re: How do you transparently implement the same web service (WSDL) with java axis and .NET ?
 
"tomjbr.10216233@bloglines.com" <tomjbr.10216233@bloglines.com> wrote in
news:1115759867.862991.157300@o13g2000cwo.googlegr oups.com:
> The thing I want to do is to be able to invoke multiple web services
> which are supporting the same WSDL interface.


If this is the case - isnt it a matter of just using one webservice client
and changing the URL? Or have I overlooked something?

I have webservices that are published at multiple locations, and I merely
change the URL in the client to point them at the right place.

> And I want to do it with polymorphism, so I can do it dynamically when
> I in runtime find a new URL supporting the same WSDL interface, without
> having to generate a new class each time.


Im not sure where polymorphism fits into this, but if you dont want to
generate, and if they are new interfaces, then you are going to have to
manually parse the WSDL.

> And my point of doing the UDDI comparison was that just if you can not
> even do this stuff with hardcoding some URL strings (which I have
> tried) , then how are you supposed to implement software that are using
> an UDDI server to dynamically find and bind to URL's that support a
> certain WSDL interface that has been registered in an UDDI tModel
> structure.


Because users consume the interface before hand, then when they find it
with UDDI they just change the URL that the webservice client code connects
to.


--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"

Blog: http://blogs.atozed.com/kudzu


All times are GMT. The time now is 03:26 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.