Java/.NET Interoperability with the Microsoft.com Web Service

 

Keith Organ
Arkitec Ltd.

March 2004

Copyright © 2004 Arkitec Ltd.

Applies to:
   Microsoft .NET
   Web Services Enhancements 1.0 for Microsoft .NET SP1
   WS-Security specification
   webMethods GLUE 4.1.2 Professional

Summary: This article covers interoperability between the Microsoft.com Web service, built with Web Services Enhancements 1.0 SP1 for Microsoft .NET, and a Java client. See how the WS-Security specification and implementation can be used to validate a Web service call from Java to Microsoft .NET. GLUE 4.1.2 Professional from webMethods will be used to enable WS-Security functionality for the Java client. (9 printed pages)

Contents

Introduction
Before You Begin
Building the Client Application
Adding WS-Security
Exploring the Functionality of the Microsoft.com Web Service
Conclusion
Additional Information
Related Books

Introduction

The Microsoft.com Web Service is an XML Web service that allows developers to integrate content from the MSDN library, TechNet, and other Microsoft resources or services. Third-party developers and Microsoft product groups use it to provide a common platform for exposing and utilizing Microsoft content and services. Currently, Version 1.0 of the Microsoft.com Web service is available. This initial release exposes the Microsoft.com "Top Downloads" information. In future releases a much broader range of content will be made available.

This article demonstrates how to consume and utilize the Microsoft.com Web Service from a Java environment and shows a working example of using WS-Security to validate client calls to the .NET Web service. Interoperability between a .NET WS-Security secured Web service and a Java client is also shown. For details on how to build a .NET client to talk to the Microsoft.com Web service, please refer to the Microsoft.com Web Service SDK.

Before You Begin

The Microsoft.com Web service requires authentication using an access token. To use the examples in this article you must obtain a developer token. Click here to obtain a developer token.

You must have the Java SDK version 1.3 or above installed. Java SDKs are available from IBM, BEA, and Sun.

This example uses the GLUE Web services stack from webMethods. You should download and install the latest version of GLUE. We used version 4.1.2 for this article. Follow the instructions for licensing your GLUE installation supplied by webMethods and also add the location of the GLUE-ALL.jar to your CLASSPATH environment variable. Typically this is located in C:\TME\glue\lib\GLUE-ALL.jar. This will allow you to easily run the command-line tools used in the examples.

Building the Client Application

In this section we will create the proxy and associated data files to enable us to communicate with the .NET Web service. A client application will be built that uses the proxy to invoke methods on the Web service.

To generate the Java proxies for Microsoft.com

  1. Open a command prompt.
  2. Create a new folder to contain the client and related files called MSWebService and change to that folder.
  3. Enter the following to create the helper class and support classes required to consume the Web service: Note: You must configure GLUE licensing and your CLASSPATH environment variable before executing the below statements. Refer to the Before You Begin section in this article.
    wsdl2java http://ws.microsoft.com/mscomservice/mscom.asmx?WSDL 
    

A helper class and a number of data classes are generated. Open the helper class MsComServicesHelper.java in your favourite programming editor and examine the contents. It contains a bind() method which will allow a client to invoke the Web service.

Open the IMsComServicesSoap.java file. This lists the methods that are exposed by the Web service. By default, the helper class does not use WS-Security to invoke the Web service. The Microsoft.com Web service requires WS-Security to authenticate client calls. By building a simple test class, we can prove that calls from clients not using WS-Security will be rejected.

To create the Web Service test client

  1. Create a new file called WSTest.java and open it for editing. Add code to the new class so that it calls the bind() method of the helper class. Invoke the GetVersion() method of the Web service. Your code should appear as below:
    public class WSTest
    {
       public static void main(String args[])
       {
          try
          {   
             IMsComServicesSoap ws = MsComServicesHelper.bind();
             String version = ws.GetVersion();
             System.out.println("Version: " + version);
          }
          catch(Exception e)
          {
             e.printStackTrace();
          }
       }
    }
    
  2. Save the WSTest.java file.
  3. From the command prompt, compile the new WSTest class and all the classes generated by wsdl2java by entering the following:
    javac *.java
    
    
  4. Run the WSTest class to verify that it attempts to connect to the Web service.
    java WSTest
    
    
  5. The WSTest class executes and attempts to connect to the Microsoft.com Web service. After a short delay, you see the following message:
    [STARTUP] GLUE Professional 4.1.2 (c) 2001-2003 The Mind Electric
    
    electric.util.WrappedException: SOAPException( Server: The security token could
    not be authenticated or authorized )
            at electric.proxy.handler.Proxy.getCompatibleException(Unknown Source)
            at electric.proxy.handler.Proxy.invoke(Unknown Source)
            at electric.util.proxy.proxy3.InvocationAdaptor.invoke(Unknown Source)
            at $Proxy0.GetVersion(Unknown Source)
            at Test.main(Test.java:13)
    

The Microsoft.com Web service rejects the invocation from our test client, as we have not supplied the necessary WS-Security credentials.

Adding WS-Security

To add WS-Security to the Java application, you will need your developer token that you obtained from Microsoft. Note that the token and PIN are not sent in plain text, but are in fact scrambled. Due to a compatibility problem between GLUE and .NET, we also need to modify the date stamp that is attached to the outgoing message. GLUE appends milliseconds to the date/time stamp that by default is incompatible with WSE 1.0. WSE 1.0 does not accept date/time stamp formats with the optional milliseconds included, though it should be noted that WSE 2.0 does not have this restriction. As the Microsoft.com Web service has been created using WSE 1.0, it is necessary to remove the milliseconds from the date/time stamp.

To add WS-Security to the test client

  1. To use WS-Security we need to modify the helper class that was generated by the wsdl2java tool. Open MsComServicesHelper.java for editing.
  2. Modify the code in the bind() method so that WS-Security is used.
    Note: You will need to register for a Developer token prior to implementing this class. Refer to the Building the Client Application section earlier in this article. Remember to add your developer token and PIN to the code at the appropriate location.

    The code for the completed helper class is listed below:

    import java.util.Date;
    import electric.glue.context.ProxyContext;
    import electric.registry.Registry;
    import electric.registry.RegistryException;
    import electric.soap.security.WSSContext;
    import electric.soap.security.tokens.UsernameToken;
    import electric.util.time.XSDDateFormat;
    
    public class MsComServicesHelper
    {
         private static final String ID = "YOUR DEVELOPER TOKEN HERE";
         private static final String PIN = "YOUR TOKEN PIN HERE";
         
         public static IMsComServicesSoap bind() throws RegistryException
        {
          // Set up the WS-Security context
          ProxyContext proxyContext = new ProxyContext();
          WSSContext wss = new WSSContext();
             
          // Uncomment the following 2 lines ONLY if you are using a proxy to connect
          // to the Internet. Fill in the name of the proxy server and proxy port no.
    
          // proxyContext.setProxyHost("myproxy");
             // proxyContext.setProxyPort(8080);
    
          proxyContext.setWSSContext( wss );
          
          // Add a UsernameToken to the outgoing request
          UsernameToken usernameToken = new UsernameToken(ID, PIN);
          usernameToken.setUseNonce(true);
          
          // Get the current Date/Time for the Nonce. 
          // We need to fix it to work with WSE 1.0.   
          XSDDateFormat d = new XSDDateFormat();
          String date = d.format(new Date());
          String newDate = date.substring(0,date.length()-5) + 
                            date.charAt(date.length()-1);
       
          // set the created date
          usernameToken.setCreated(newDate);
          
          wss.out.addSecurityToken( usernameToken );
          return 
             bind( "http://ws.microsoft.com/mscomservice/mscom.asmx?WSDL",
                   proxyContext );
        }
    
         public static IMsComServicesSoap bind( String url ) throws RegistryException
        {
           return (IMsComServicesSoap) 
             Registry.bind( url, IMsComServicesSoap.class );
        }
        
         public static IMsComServicesSoap bind( String url, ProxyContext pc ) throws RegistryException
        {
           return (IMsComServicesSoap) 
                Registry.bind( url, IMsComServicesSoap.class, pc );
        }
    }
    
    
  3. Save your changes to the helper class. Recompile your .java files by executing the following:
    javac *.java. 
    
    
  4. You are now in a position to test the WSTest client again. From the command prompt, execute:
    java WSTest
    
    
  5. Confirm that you get a response from the Web service similar to the below:
    [STARTUP] GLUE Professional 4.1.2 (c) 2001-2003 The Mind Electric
    
    Microsoft.Com Platform Services 1.0 Beta
    

We are now invoking the .NET Web service from a simple Java client using WS-Security to authenticate the client requests.

Exploring the Functionality of the Microsoft.com Web Service

It is possible to retrieve information about the top downloads from the Microsoft website using the Web service.

To retrieve a list of top downloads from the Microsoft website

  1. Modify your test class to retrieve top download information by adding the following code:
    public class WSTest
    {
       public static void main(String args[])
       {
          try
          {   
             String CultureID = "en-US";
             TopType DesiredTopType = TopType.fromString("Popular");
             int NumDownloads = 5;
    
             IMsComServicesSoap ws = MsComServicesHelper.bind();
             String version = ws.GetVersion();
             System.out.println(version);
             Downloads d = ws.GetTopDownloads(DesiredTopType, 
                                     NumDownloads, CultureID);
             DownloadSummary[] ds = d.DownloadSummary;
    
             for (int i=0; i< ds.length;i++)
             {
                System.out.println(ds[i].RankInThisCulture);
                System.out.println(ds[i].ShortName);
                System.out.println(ds[i].ShortDescription);
                System.out.println(ds[i].DetailsUrl);
                System.out.println();
             }
          }
          catch(Exception e)
          {
             e.printStackTrace();
          }
       }
    }
    
  2. Save your changes to the helper class. Recompile your .java files by executing the following:
    javac *.java. 
    
    
  3. You are now in a position to test the WSTest client again. From the command prompt, execute:
    java WSTest
    
    
  4. Confirm that you get a response from the Web service similar to the one below:
    1
    DirectX 9.0b End-User Runtime
    Microsoft DirectX(r) 9.0b End-User Runtime will update your current version of Dir
    EctX, the core Windows(r) technology that drives high-speed multimedia and games
    on the PC.
    http://www.microsoft.com/downloads/details.aspx?FamilyID=141D5F9E-07C1-462A-BAEF
    -5EAB5C851CF5&displaylang=en
    
    ...
    

Conclusion

You can now create a more advanced Java client or Web-based application using the methods outlined in this article. Hopefully you now see how easy it is to add the Microsoft.com Web services features to your Java-based applications, and also how WS-Security can be used between the .NET and Java platforms.

Additional Information

This article was created by Keith Organ of Arkitec Ltd, a UK-based company specializing in .NET/J2EE interoperability solutions. Arkitec is a co-author of the Microsoft patterns & practices guide, Application Interoperability: Microsoft .NET and J2EE.

For more information on .NET/J2EE Interoperability, visit the Arkitecs website to find interoperability case studies, example code, and details of interoperability and migration workshops.

Related Books

Microsoft .Net and J2EE Interoperability Toolkit

Understanding Web Services Specifications and the WSE

Show: