Using Web Service Attachments

Using attachments on a Web Service is not that complicated because it only involves defining a new data type. We can best illustrate the new data type by looking at the deployment configuration file shown in Listing 10.40.

Listing 10.40
start example
 <deployment xmlns=""  xmlns:java=""> <service name="File" provider="java:RPC"> <parameter name="className" value=""/> <parameter name="allowedMethods" value="*"/> <operation name="upload" qname="operNS:upload" xmlns:operNS="" returnQName="returnqname" returnType="rtns:long" xmlns:rtns=""> <parameter name="dh" type="ns1:DataHandler" xmlns:ns1=""/> </operation> <typeMapping xmlns:ns1="" deserializer="org.apache.axis.encoding.ser.JAFDataHandler-DeserializerFactory" languageSpecificType="java:javax.activation.DataHandler" qname="ns1:DataHandler" serializer="org.apache.axis.encoding.ser.JAFDataHandler-SerializerFactory" encodingStyle=""/> </service> </deployment> 
end example

In Listing 10.40, the deployment file has a different definition of the method parameter than when using method calls that use standard Java data types. The parameter name dh has a value of ns1:DataHandler . The qname of the XML element typeMapping is identical to the parameter name dh . This means that when the parameter dh is serialized to and from the SOAP message, the serialization used is the factories JAFDataHandlerDeserializerFactory and JAFDataHandlerSerializerFactory . The factories instantiate classes that serialize Direct Internet Message Encapsulation (DIME) encoded data.

What is fundamental about this change in data mapping is that in theory you can process any kind of data by simply defining the correct mapping. And, in this context, the XML element typeMapping resembles the betwixt mapping file because it specifies how to read and write the data.

To support the reading and writing of the DIME encoded data, the server has to use a special class that contains the data. Listing 10.41 is the Web Service implementation that can process an attachment.

Listing 10.41
start example
 public class File { public long upload( DataHandler dh) throws Exception { if( dh != null) { InputStream iis = (InputStream)dh.getContent(); if( iis != null) { FileOutputStream fos; ObjectOutputStream oos;  fos = new FileOutputStream( "/home/cgross/temp/build.xml"); byte rawData[] = new byte[ iis.available()]; rawData); fos.write( rawData); fos.close(); return 0; } else { System.out.println( "Ooops not a stream"); } } return -1; } } 
end example

In Listing 10.41, the class File has a single parameter, which is the data type DataHandler . The class DataHandler is from the activation package and contains the attachment data as a stream. The stream is then read as an input stream using the method getContent . From there, the input stream is converted to an array of bytes that are written to a file. The stream can represent a file, a serialized Java object, or a picture. The stream can be any stream of bytes.

Listing 10.41 expects a stream of bytes, which is a file sent by the client as shown in Listing 10.42.

Listing 10.42
start example
 private static void sendFile( String filename, String url) throws Exception { DataHandler dhSource = new DataHandler( new FileDataSource( filename)); org.apache.axis.client.Service service = new org.apache.axis.client.Service(); org.apache.axis.client.Call call = (org.apache.axis.client.Call) service.createCall(); call.setTargetEndpointAddress( new URL(url)); call.setOperationName( new QName("","upload") ); QName qnameAttachment = new QName("", "DataHandler"); call.registerTypeMapping(dhSource.getClass(),  qnameAttachment, JAFDataHandlerSerializerFactory.class,  JAFDataHandlerDeserializerFactory.class); call.addParameter( "dh", qnameAttachment,  ParameterMode.IN ); call.setReturnType( new QName( "", "long"));  call.invoke( new Object[] { dhSource } ); } 
end example

The client code in Listing 10.42 uses a coding notation that is similar to the manual coding example (Listing 10.16). There are a couple of differences, though. The first difference is the usage of the class DataHandler to load a file. Another difference is what is new in this manual coding example: the usage of the method registerTypeMapping . In the deployment file of the server, DIME encoded data is managed using some special classes. On the client side, though, there is no deployment file to define a mapping. Therefore, the mapping needs to be defined using code like that in Listing 10.42. Notice that the parameters of the method registerTypeMapping use the same data types as the deployment files JAFDataHandlerSerializerFactory and JAFDataHandlerDeserializerFactory . Then, to invoke the Web Service, the method invoke is called using an array of objects.

When using attachments, you need to remember that they use special processors. DIME attachments are a standard, but they need special processing, which is not always supported. Using custom serialization works if the developer controls the sender and receiver. However, custom serialization may not work if the sender and receiver have small differences in implementation. It is similar to when a British English speaker and American English speaker hear the word "subway." Yes, both know the word, but there is a difference in what it represents to each person. A British person will consider a subway to be an underpass where pedestrians can walk underneath some object. An American will consider a subway to be a form of city transportation, or what a British person considers the "tube" or " underground ." It's therefore very important when you're developing Web Services that you never ignore the topic of interoperability. Doing so could result in huge integration problems at a later point in time.

Applied Software Engineering Using Apache Jakarta Commons
Applied Software Engineering Using Apache Jakarta Commons (Charles River Media Computer Engineering)
ISBN: 1584502460
EAN: 2147483647
Year: 2002
Pages: 109 © 2008-2017.
If you may any questions please contact us: