As discussed in the introduction, the samples we are going to show will demonstrate a Java client taking a document created in Microsoft Word and sending it to a .NET-based Web service. When the Web service receives this document, it will be stored in a directory named Files. We'll then show how a .NET client can make a call to the Web service to request the document. This document flow is shown in Figure 14.1.

click to expand
Figure 14.1: How the sample code is used to send attachments from a Java client to .NET.

All the attachment- related calls using .NET will be made with Microsoft WSE (Web Services Enhancements) 1.0. All the equivalent calls in Java will be performed using GLUE 4.0.1.

Downloading and Installing Microsoft WSE

This sample assumes that Microsoft WSE (Web Services Enhancements) 1.0 Service Pack 1 has been installed. This software package, available from webservices , must be installed for the .NET client to compile correctly. Additional information about downloading and installing the product can be found in the "Downloading and Installing Microsoft WSE" section of Chapter 13, "Web Services Interoperability, Part 1: Security."

Setting Up the Document Web Service

The first task in showing the sample is to create the Web service itself. This Web service, based on .NET, will offer two methods :

 String AddDocument(String documentName) String GetDocument(String documentName) 

The AddDocument method is used to send a binary attachment from a client to the Web service. The Web service will nominate a directory for storing the attachment. The GetDocument method works in reverse and returns an attachment to the client. Each method accepts a String that contains the filename of the document and returns a String to indicate whether the request was successful.

The sample code for the Web service can be found in the C:\Interoperability\Samples\Advanced\Attachments\dotNET\WebService directory. This sample code needs to be compiled using the supplied NAnt script, and a virtual directory needs to be created to host this .NET Web service.

To create the virtual directory, launch Internet Information Services (IIS) Manager from Start/Program Files/Administrative Tools. Within the IIS Manager, navigate through the Local Computer entry to find the Default Web Site. Right-click the Default Web Site entry, and select New/Virtual Directory. Within this wizard, set the alias of the directory to dotNETDocService , as shown in Figure 14.2.

click to expand
Figure 14.2: Creating the virtual directory required for the .NET Web service.

For the path , enter the location of the Web service, C:\Interoperability\Samples\Advanced\Attachments\dotNET\WebService , as shown in Figure 14.3.

click to expand
Figure 14.3: Specifying the directory for the .NET Web service.

Finish running the wizard to complete the setup of the virtual directory. When the Web service receives a request to add an attachment, the attachment will be automatically stored in the C:\Interoperability\Samples\Advanced\Attachments\Files directory. You should ensure that the account the Web service is running under (by default, ASPNET) has access to this directory. This check can be made by using Windows Explorer. Before you run the Java client, observe how the Files directory is empty.

Running the Java Client

In the sample, the Java client sends a Microsoft Word document to the Web service. This document is named stock.doc , and it can be found in the same directory as the Java client code, C:\Interoperability\Samples\Advanced\Attachments\Java\Client. If you have Microsoft Word installed, open the file now. If you do not have Microsoft Word installed, this file can also be opened using WordPad.

As shown in Figure 14.4, the Word document is simply a sample certificate of ownership ”based on the stock trading samples we've been using throughout the book. This sample document can be used to demonstrate a scenario where certificates were generated using a J2EE application, forwarded to a .NET Web service, and then retrieved by a .NET client (which of course, with a .NET Add-In for Microsoft Office, could be Word itself).

click to expand
Figure 14.4: The Microsoft Word document that will be exchanged.

To show the client, navigate to the C:\Interoperability\Samples\Advanced\Attachments\Java\Client directory, and build and run the sample code using Ant with the run target. After the Word document has been sent to the Web service, the following message will be displayed:

 Message from Web Service: stock.doc accepted. 

The Web service has taken the file sent by the Java client and stored it in the Files directory (C:\Interoperability\Samples\Advanced\Attachments\Files). You can confirm this by using Windows Explorer to navigate to this location and reopening the file. The file doesn't get deleted from the Java client directory ”this is like sending an attachment via e-mail.

The sending of this attachment was made possible by a number of underlying GLUE APIs that were used by the Java client. Examining the file in the Client subdirectory shows how this works.

First, the Word document is read into a RandomAccessFile by the client. This literally turns the file into a stream of UTF8-encoded bytes, which is required for forwarding it with the Web service call.

 RandomAccessFile raf      = new RandomAccessFile(FILE_PATH+"\"+"stock.doc","r"); if( raf.length() > Integer.MAX_VALUE )     throw new IOException("File too big to send"); byte[] buffer = new byte[(int)raf.length()];; 

Notice how this read is limited by the size of the buffer, defined by Integer.MAX_VALUE . (For a 16-bit integer, this is 64k.) This implicit buffer size currently limits the size of the files that can be sent, which is something that we will discuss after the sample code.

 Context threadContext = Context.thread(); MIMEData attachment = new MIMEData(buffer,"application/msword"); threadContext.setProperty("unreferencedAttachments",attachment); 

After we have the buffer containing the byte representation of the document, we use GLUE to build a new context and we use the MIMEData class to put the document into an attachment object. This attachment is set as a property of the client context.


The class in GLUE to load the attachment is named MIMEData (instead of DIMEData , which you might have been expecting). This class has been named this way to allow backward compatibility. A setting in the GLUE global config.xml file can be switched to configure this class for either MIME or DIME. By default, and for our example, the MIMEData class is building a DIME attachment.

Finally, the Web service is bound, and a call to the AddDocument class is made.

 String url      = "http://localhost/dotNETDocService/DocumentService.asmx?WSDL"; IDocumentServiceSoap service      = (IDocumentServiceSoap)Registry.bind(url,         IDocumentServiceSoap.class); String result = service.AddDocument("stock.doc"); 

The filename of the document is passed as a parameter of the method call. This parameter instructs the Web service what the name of the file should be when it is saved. The Web service itself will return a String indicating if the file was accepted.

Before we look at retrieving the Word document by using a .NET client, let's take a quick look at the AddDocument method itself. This method can be found in the DocumentService.asmx.cs, located in the C:\Interoperability\Samples\Advanced\Attachments\dotNET\WebService directory.

 if (HttpSoapContext.RequestContext == null)     throw new          ApplicationException("Only SOAP requests are permitted."); if (HttpSoapContext.RequestContext.Attachments.Count != 1) {     throw new          ApplicationException("1 attachment required for this method."         +HttpSoapContext.RequestContext.Attachments.Count         +" were sent"); } 

The first check for this method ensures that it is a true SOAP request (attachments cannot be forwarded using any other method), and that only one attachment is forwarded as part of the request. You'll notice that the WSE 1.0 class defines an array of attachments as part of the HttpSoapContext class.

After these items have been validated , a process is used that is the opposite of how the client attached the document. First the attachment is converted into a stream of bytes using the BinaryReader from the System.IO namespace.

 BinaryReader br =      new BinaryReader(HttpSoapContext.RequestContext.Attachments[0].Stream); byte[] buffer = br.ReadBytes(Int32.Parse(     br.BaseStream.Length.ToString())); br.Close(); 

Once the attachment has been converted to a stream of bytes, a FileStream is used to write the file to disk.

 System.IO.FileStream output      = System.IO.File.Create(FILE_PATH+@"\"+documentName); output.Write(buffer,0,buffer.Length); output.Close(); 

Assuming this is successful, the return message is sent back to the client indicating that the file has been accepted.

Running the .NET Client

We've now seen how the Java client makes a request to the .NET Web service and how it attaches the Word document as an attachment to the call. Using similar methods, the Web service is able to convert the attachment back from a binary stream and write the file to disk.

The final piece of the sample is to show how a client in .NET can use the WSE libraries to make a call to the Web service and request the attachment. The sample code to show this can be found in the C:\Interoperability\Samples\Advanced\Attachments\dotNET\Client directory. Use the NAnt script to build and run the code in this directory. When run, the client will display the following:

 Message from Web Service: Document Attached File saved. 

The first message is the String response, sent from the Web service when the GetDocument method was called. This message indicates the document was attached to the response. After the document is extracted and saved to disk, the client reports that the file is now saved. If you look in the Client directory, you should now be able to confirm this by observing that a stock.doc file has been created. The contents of this file can again be validated by opening the document in Microsoft Word.

This operation works in much the same way that the file upload task did. If we look at the Client.cs class, the first task the client performs is to call the GetDocument method of the .NET Web service.

 DocumentService ds = new DocumentService(); Console.WriteLine("Message from Web Service: "     +ds.GetDocument("stock.doc")); 

This method (which can be viewed by again opening the DocumentService.asmx.cs class in the WebService subdirectory) starts by first checking that this is a SOAP request, and then it creates a reference to the existing response context.

 if (HttpSoapContext.RequestContext == null)     throw new          ApplicationException("Only SOAP requests are permitted."); SoapContext responseContext = HttpSoapContext.ResponseContext; 

After this is done, the attachment is appended to the context by using the DimeAttachment class from the Microsoft.Web.Services namespace.

 try {     DimeAttachment attachment          = new DimeAttachment("application/msword",         TypeFormatEnum.MediaType, FILE_PATH+@"\"+documentName);     responseContext.Attachments.Add(attachment); } catch (System.IO.FileNotFoundException) {     throw new ApplicationException(documentName         +" does not exist on the server."); } 

Notice how using the DimeAttachment class doesn't require the document to be converted into a stream of bytes, although this can still be done by using an overloaded constructor. If the file is not found (based on the file name that was passed to the method), an ApplicationException is raised. This exception will be received by the client as a SoapFault .

With the attachment complete, the Web service now returns the completion string.

 return "Document Attached"; 

Getting back to the client, after the Web service call is made, the file is extracted from the context into a byte array by using the BinaryReader and the file is then saved to disk. This is exactly the same operation used by the Web service to add the document sent by the Java client.

 BinaryReader br = new BinaryReader(     ds.ResponseSoapContext.Attachments[0].Stream); byte[] buffer      = br.ReadBytes(Int32.Parse(br.BaseStream.Length.ToString())); br.Close();              System.IO.FileStream output =      System.IO.File.Create(FILE_PATH+@"\"+"stock.doc"); output.Write(buffer,0,buffer.Length); output.Close();              Console.WriteLine("File saved."); 

Finally, the client displays that the file is saved.

Two-Way File Operations

In this sample, we've seen how a Java client sends an attachment with a Web service request, and how a .NET client receives an attachment by making a corresponding request to the service. There is of course nothing to stop each client from both sending and receiving attachments to the Web service. For the .NET client, this can be achieved by using the DimeAttachment class, but in this case it will be used on the client. For the Java client, the Web service is bound and then the attachment is added to the context just before the actual method is called.

Extending the clients in this way offers a number of possibilities for using attachments in conjunction with Web services. For example, an extension of this sample could be to create a File Manager Web service, which could have the ability to upload, download, list, and display the properties of files via a Web service. Using the techniques in this chapter, the client for this Web service could be .NET, Java, or anything else that supports the DIME specification.

Microsoft. NET and J2EE Interoperability Toolkit
Microsoft .NET and J2EE Interoperability Toolkit (Pro-Developer)
ISBN: 0735619220
EAN: 2147483647
Year: 2003
Pages: 132
Authors: Simon Guest © 2008-2017.
If you may any questions please contact us: