Consuming MTOM/XOP web services from Axis 1

Axis 1 does not support MTOM specification for the client side (and it only supports this specification partially for the server side [1]). However, sometimes this combination is required due to technologic restrictions.

In this tutorial is described a way to access MTOM/XOP web services for file transfers using Axis 1 as client by implementing two Java projects:

  1. Creating a MTOM/XOP web service with Apache CXF 2
  2. Consuming the web service with Apache Axis 1

1. Creating a MTOM/XOP web service with Apache CXF

Let’s create a simple web service exposing a XOP node to download a file. Several samples to build a CXF web services client are available [2], so only main resources are detailed.

1.a. Web service interface

package cxf.mtom.server.service;

import javax.jws.WebService;

import cxf.mtom.server.bean.ResponseDownloadFile;

@WebService
public interface DownloadFile {

	ResponseDownloadFile getFile() throws Exception;

}

1.b. Web service implementation

package cxf.mtom.server.service;

import java.io.File;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.jws.WebService;

import cxf.mtom.server.bean.ResponseDownloadFile;

@WebService(endpointInterface = "cxf.mtom.server.service.DownloadFile", serviceName = "DownloadFileWS")
public class DownloadFileImpl implements DownloadFile {

	public ResponseDownloadFile getFile() throws Exception {
		ResponseDownloadFile rdf = new ResponseDownloadFile();
		rdf.setFileName("c:/tmp/readme.txt");
		rdf.setFileType("plain/text");
		rdf.setFile(new DataHandler(new FileDataSource(new File("C:/tmp/readme.txt"))));
		return rdf;
	}

}

1.c. Web service response bean

package cxf.mtom.server.bean;

import javax.activation.DataHandler;

/**
 * Web service response bean.
 */
public class ResponseDownloadFile {

	private String fileName;
	private String fileType;
	private DataHandler file;

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getFileType() {
		return fileType;
	}

	public void setFileType(String fileType) {
		this.fileType = fileType;
	}

	public DataHandler getFile() {
		return file;
	}

	public void setFile(DataHandler file) {
		this.file = file;
	}
}
 

1.d. Spring configuration for CXF

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
 					http://www.springframework.org/schema/beans/spring-beans.xsd
 					http://cxf.apache.org/jaxws
 					http://cxf.apache.org/schemas/jaxws.xsd">

  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
  <jaxws:endpoint id="downloadfile"
                  implementor="cxf.mtom.server.service.DownloadFileImpl"
                  address="/DownloadFileWS">
       <jaxws:properties>
           <entry key="mtom-enabled" value="true"/>
       </jaxws:properties>	
  </jaxws:endpoint>
</beans>

1.e. Web descriptor

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
  <display-name>DownloadFile</display-name>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:cxf.xml</param-value>
  </context-param>
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  <servlet>
    <servlet-name>CXFServlet</servlet-name>
    <servlet-class>
        org.apache.cxf.transport.servlet.CXFServlet
    </servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>CXFServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
</web-app>

1.f. Generated WSDL (p. e. http://localhost:8080/cxfMTOMServer/services/DownloadFileWS?wsdl)

<?xml version='1.0' encoding='utf-8'?>
<wsdl:definitions name="DownloadFileWS"
targetNamespace="http://service.server.mtom.cxf/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://service.server.mtom.cxf/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
    <xs:schema elementFormDefault="unqualified"
    targetNamespace="http://service.server.mtom.cxf/" version="1.0"
    xmlns:tns="http://service.server.mtom.cxf/"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="getFile" type="tns:getFile" />
      <xs:element name="getFileResponse"
      type="tns:getFileResponse" />
      <xs:complexType name="getFile">
        <xs:sequence />
      </xs:complexType>
      <xs:complexType name="getFileResponse">
        <xs:sequence>
          <xs:element minOccurs="0" name="return"
          type="tns:responseDownloadFile" />
        </xs:sequence>
      </xs:complexType>
      <xs:complexType name="responseDownloadFile">
        <xs:sequence>
<!-- XOP Node -->          
          <xs:element minOccurs="0" name="file"
          type="xs:base64Binary" />
          <xs:element minOccurs="0" name="fileName"
          type="xs:string" />
          <xs:element minOccurs="0" name="fileType"
          type="xs:string" />
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
  </wsdl:types>
  <wsdl:message name="getFileResponse">
    <wsdl:part element="tns:getFileResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getFile">
    <wsdl:part element="tns:getFile" name="parameters"></wsdl:part>
  </wsdl:message>
  <wsdl:portType name="DownloadFile">
    <wsdl:operation name="getFile">
      <wsdl:input message="tns:getFile" name="getFile">
      </wsdl:input>
      <wsdl:output message="tns:getFileResponse"
      name="getFileResponse"></wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="DownloadFileWSSoapBinding"
  type="tns:DownloadFile">
    <soap:binding style="document"
    transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getFile">
      <soap:operation soapAction="" style="document" />
      <wsdl:input name="getFile">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getFileResponse">
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="DownloadFileWS">
    <wsdl:port binding="tns:DownloadFileWSSoapBinding"
    name="DownloadFileImplPort">
      <soap:address location="http://localhost:8080/cxfMTOMServer/services/DownloadFileWS" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

2. Consuming the web service with Apache Axis 1

And now the Axis 1 client to consume CXF web service.

2.a. Create standard axis client through WSDL file

Use wsdl2java tool [3].

2.b. Axis client configuration (client-config.wsdd)

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

    <handler name="log" type="java:org.apache.axis.handlers.LogHandler"/>
    
    <!-- MTOM Axis 1 Handler -->
    <handler name="xop" type="java:axis.mtom.client.handler.XOPHandler">
        <parameter name="serviceName" value="{http://service.server.mtom.cxf/}DownloadFileWS"/>
        <parameter name="operationName" value="getFile"/>
        <parameter name="mtomNodePath" value="getFileResponse.return.file"/>
    </handler>
    
    <globalConfiguration>
       <requestFlow>
           <handler type="log"/>
       </requestFlow>
       <responseFlow>
            <handler type="log"/>
            <handler type="xop"/>
       </responseFlow>
    </globalConfiguration>
    
    <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
    
</deployment>

2.c. Axis Response Handler for XOP

package axis.mtom.client.handler;

import java.io.InputStream;
import java.io.StringWriter;
import java.util.Iterator;

import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.attachments.AttachmentPart;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.handlers.BasicHandler;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Retrieve MTOM/XOP file referenced by "mtomNodePath" parameter 
 * from "client-config.wsdd" file.
 * Exposes a Stream including file content to clients through 
 * ThreadLocal mechanism. 
 *
 */
public class XOPHandler extends BasicHandler {

	// "client-config.wsdd" parameters
	private static final String HANDLER_OPTION_MTOM_NODE_PATH = "mtomNodePath";
	private static final String HANDLER_OPTION_OPERATION_NAME = "operationName";
	private static final String HANDLER_OPTION_SERVICE_NAME = "serviceName";
	
	// Stream including file content 
	private static ThreadLocal documentStream = new ThreadLocal();
    public static InputStream getDocumentStream() {
        return (InputStream)documentStream.get();
    }
    
	/**
	 * Copy Stream reference to file content by searching specified SOAP node on client-config.wsdd file.
	 */
    public void invoke(MessageContext msgContext) throws AxisFault {
    	
    	// Only process targeted service and operation
    	if (isTargetedServiceAndOperation(msgContext)) {
    	
			// Recover SOAP node from client-config.wsdd parameter
			String mtomNodePath = (String) getOption(HANDLER_OPTION_MTOM_NODE_PATH);
			if (mtomNodePath == null) {
				System.out.println("No mtomNodePath parameter specified on client-config.wsdd file");
			} else {
				
				String[] pathToNode = mtomNodePath.split("\\.");
				int nodesLevel = pathToNode.length;
				
				try {
					
					// Recover SOAP Body
					Message msg = msgContext.getResponseMessage();
					SOAPMessage soapMessage = msgContext.getResponseMessage();
		            SOAPBody soapBody = soapMessage.getSOAPBody();
		            
		        	// Search mtomNodePath in SOAP Body
		            Node currentNode = null;
		            int currentNodeLevel = 0;
		            NodeList nodeList = soapBody.getChildNodes();
		            while (currentNodeLevel < nodesLevel && nodeList != null) {
		            	currentNode = null;
		                for (int i = 0; i < nodeList.getLength(); i++) {
		                	if (nodeList.item(i).getLocalName().equals(pathToNode[currentNodeLevel])) {
		                		currentNode = nodeList.item(i);
		                		break;
		                	}
		                }
		                if (currentNode != null) {
		                    nodeList = currentNode.getChildNodes();
		                } else {
		                	nodeList = null;
		                }
		            	currentNodeLevel++;
		            }
		            
		            // mtomNodePath found
		            if (currentNode != null) {
		            
			            // Recover reference to SOAP Attachment from node attribute "Include" 
		            	String attachmentRef = null;
		            	if (currentNode.getChildNodes() != null && 
						    currentNode.getChildNodes().getLength() > 0) {
				    		NamedNodeMap nnm = currentNode.getChildNodes().item(0).getAttributes();
				    		for (int j = 0; j < nnm.getLength(); j++) {
				    			attachmentRef = nnm.item(j).getNodeValue();
				    		}
				    		// (!) Delete XOP node to prevent Axis service unmarshalling errors
				    		currentNode.getParentNode().removeChild(currentNode);
		            	} else {
		            		System.out.println("No reference founded at node " + mtomNodePath);
		            	}
			    		
						// Recover SOAP Attachment from attachments using the reference
		            	if (attachmentRef != null) {
		            		
				            Iterator attachments = msg.getAttachments();
							while (attachments.hasNext()) {
								AttachmentPart attachmentPart = (AttachmentPart)attachments.next();
								if (attachmentPart.getContentIdRef().equals(attachmentRef)) {
								    documentStream.set(attachmentPart.getDataHandler().getInputStream());
								}
							}
							
				            // Perform SOAP Body operations to persist changes
							TransformerFactory tff = TransformerFactory.newInstance();
				            Transformer tf = tff.newTransformer();
				            Source sc = soapMessage.getSOAPPart().getContent();
				            StringWriter modifiedBody = new StringWriter();
				            StreamResult result = new StreamResult(modifiedBody);
				            tf.transform(sc, result);            
				            Message modifiedMsg = new Message(modifiedBody.toString(), false);
				            msgContext.setResponseMessage(modifiedMsg);
				            
		            	} else {
		            		System.out.println("No reference to XOP file founded at node " + mtomNodePath);
		            	}
			            
		            } else {
		            	
		            	System.out.println("Node " + mtomNodePath + " not found at Response SOAP Body");
		            	
		            }
		            
				} catch (Exception e) {
					throw new AxisFault("Handler exception", e);
				}
			}
        }
		
	}

    /**
     * Check targeted service and operation from "client-config.wsdd" parameters
     * with runtime service and operation from the web service response.
     */
    private boolean isTargetedServiceAndOperation(MessageContext msgContext) {
    	
    	boolean parametersFound = false;
    	
    	String serviceName = (String) getOption(HANDLER_OPTION_SERVICE_NAME);
        if (serviceName == null) {
        	System.out.println("No serviceName property specified on client-config.wsdd file");
        }
        
		Service locator = (Service) msgContext.getProperty(Call.WSDL_SERVICE);
		if (locator != null && locator.getServiceName().toString().equals(serviceName)) {
	    	String operationName = (String) getOption(HANDLER_OPTION_OPERATION_NAME);
	        if (operationName == null) {
	        	System.out.println("No operationName property specified on client-config.wsdd file");
	        } else if (msgContext.getOperation().getName().equals(operationName)) {
			    parametersFound = true;
	        }
		}
		
		return parametersFound;
    }
    
}

2. d. Sample web service client

package axis.mtom.client;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import axis.mtom.client.handler.XOPHandler;

import cxf.mtom.server.service.DownloadFileWSLocator;
import cxf.mtom.server.service.DownloadFileWSSoapBindingStub;
import cxf.mtom.server.service.ResponseDownloadFile;

/**
 * Access MTOM / XOP service from Axis 1
 */
public class TestClient {

	public static void main(String[] args) throws Exception {

       	// Axis client invocation
		DownloadFileWSSoapBindingStub binding =
			(DownloadFileWSSoapBindingStub) new DownloadFileWSLocator().getDownloadFileImplPort();
        ResponseDownloadFile rdf = binding.getFile();

        // Recovered file name
        System.out.println(rdf.getFileName());

        // Recovered file type
        System.out.println(rdf.getFileType());

        // UNUSED METHOD -> System.out.println(rdf.getFile());
        // Recover file content
        convertStreamToFile(XOPHandler.getDocumentStream(), rdf.getFileName());

	}

	/**
	 * Sample method: write Stream to File
	 * @param is
	 * @param fileName
	 * @throws IOException
	 */
	public static void convertStreamToFile(InputStream is, String fileName) throws IOException {

		if (is != null) {

			FileOutputStream fos = new FileOutputStream(fileName);

			byte[] buffer = new byte[1024];
			try {
				int n;
				while ((n = is.read(buffer)) != -1) {
					fos.write(buffer, 0, n);
				}
			} finally {
				is.close();
				fos.close();
			}
		}
	}
}

3. Final considerations

3.a. Sample SOAP Request

<?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>
    <getFile xmlns="http://service.server.mtom.cxf/" />
  </soapenv:Body>
</soapenv:Envelope>

3.b. Sample SOAP Response

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:getFileResponse xmlns:ns2="http://service.server.mtom.cxf/">
      <return>
        <file>
		  <!-- XOP node -->
          <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
          href="cid:89f719ee-ed51-4955-a80d-103f1d851763-4@cxf.apache.org" />
        </file>
        <fileName>c:/tmp/readme.txt</fileName>
        <fileType>plain/text</fileType>
      </return>
    </ns2:getFileResponse>
  </soap:Body>
</soap:Envelope>


--MIMEBoundary4A7AE55984E7438034
content-type: application/octet-stream
content-transfer-encoding: binary
content-id: <89f719ee-ed51-4955-a80d-103f1d851763-4@cxf.apache.org>

Binary Data.....
--MIMEBoundary4A7AE55984E7438034--

3.c. Resources

[1] http://axis.apache.org/axis2/java/core/docs/mtom-guide.html
[2] http://cxf.apache.org/docs/writing-a-service-with-spring.html
[3] http://axis.apache.org/axis/java/user-guide.html#WSDL2JavaBuildingStubsSkeletonsAndDataTypesFromWSDL

Anuncios

Upload file to Microsoft Office Sharepoint Server 2007

Microsoft Office Sharepoint Server 2007 (aka MOSS2007) provides a web services catalog in order to perform a large collection of operations on it. Morever, if enabled, WebDAV access is available.

The obvious way to upload a file to MOSS Shared Documents is the use of WebDAV protocol, however Microsoft includes a web service to perform this operation additionally. Below, both methods are shown.

Using WebDAV protocol

Required libraries: commons-httpclient-3.1.jar, commons-codec-1.3.jar, commons-logging-1.1.1.jar, log4j-1.2.15.jar, slf4j-api-1.5.6.jar, slf4j-log4j12-1.5.6.jar, jackrabbit-webdav-1.4.jar

import java.io.File;
import java.io.FileInputStream;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.jackrabbit.webdav.client.methods.PutMethod;

public class UploadFileMOSSWebDAV {

  // Proxy parameters
  static String proxyHost = "proxy.server.com";
  static Integer proxyPort = 80;
  static String proxyUser = "user";
  static String proxyPass = "pass";

  // Sharepoint parameters
  static String sharepointUser = "user";
  static String sharepointPass = "pass";
  static String sharepointDomain = "DOMAIN";

  // Shared Documents folder root
  static String sharedDocumentsRoot = "http://sharepoint.server.com/sites/IdSite/Shared Documents/";

  /**
   * Note: Setting credentials with AuthScope.ANY authentication scope (null value for host and/or realm) is
   * highly discouraged in production applications.
   * @param args
   * @throws Exception
   */
  public static void main(String... args) throws Exception {

    // HTTP client with authentication enabled
    HttpClient client = new HttpClient();
    client.getParams().setAuthenticationPreemptive(true);

    // Proxy configuration
    client.getHostConfiguration().setProxy(proxyHost, proxyPort);
    client.getState().setProxyCredentials(AuthScope.ANY,
          new UsernamePasswordCredentials(proxyUser, proxyPass));

    // Sharepoint authentication
    Credentials defaultcreds =
          new NTCredentials(sharepointUser, sharepointPass, "localhost", sharepointDomain);
    client.getState().setCredentials(AuthScope.ANY, defaultcreds);

    // Upload local file test.txt to sharedDocumentsRoot/SomeFolder/test.txt
    PutMethod method = new PutMethod(sharedDocumentsRoot + "SomeFolder/test.txt");
    RequestEntity requestEntity =
            new InputStreamRequestEntity(new FileInputStream(new File("c:/temp/test.txt")));
    method.setRequestEntity(requestEntity);
    client.executeMethod(method);
    System.out.println(method.getStatusCode() + " "+ method.getStatusText());  

  }

}

 Using MOSS Copy web service

Required libraries: commons-httpclient-3.1.jar, commons-codec-1.3.jar, commons-logging-1.1.1.jar, log4j-1.2.15.jar, activation-1.1.1.jar, saaj-api-1.3.jar, saaj-impl-1.3.2.jar, spring-core-2.5.6.jar, spring-context-2.5.6.jar, spring-beans-2.5.6.jar, spring-oxm-1.5.6.jar, spring-ws-core-1.5.6.jar, spring-xml-1.5.6.jar, xmlbeans tool

Resources: Getting started with Sharepoint Web Services

1. Retrieve WSDL from Sharepoint

WSDL for Copy web service can be found at http://sharepoint.server.com/sites/IdSite/_vti_bin/Copy.asmx?WSDL

2. Extract XSD from WSDL

Extract “s:schema” node from WSDL and include namespaces on root element


<s>
[...]
</s>

 Note. “:” replaced by “_” for visualization.

3. Generate XMLBeans objects for marshal

Use XMLBeans Ant Task to generate Java objects in order to perform marshalling and unmarshalling operations from XML

4. Web service client

import java.io.File;
import java.io.FileInputStream;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NTCredentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.util.Base64;
import org.springframework.oxm.xmlbeans.XmlBeansMarshaller;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.ws.soap.client.core.SoapActionCallback;
import org.springframework.ws.transport.http.CommonsHttpMessageSender;

import com.microsoft.schemas.sharepoint.soap.CopyIntoItemsDocument;
import com.microsoft.schemas.sharepoint.soap.DestinationUrlCollection;
import com.microsoft.schemas.sharepoint.soap.CopyIntoItemsDocument.CopyIntoItems;

public class UploadFileMOSSWS extends WebServiceGatewaySupport {

  // Proxy parameters
  static String proxyHost = "proxy.server.com";
  static Integer proxyPort = 80;
  static String proxyUser = "user";
  static String proxyPass = "pass";

  // Sharepoint parameters
  static String sharepointUser = "user";
  static String sharepointPass = "pass";
  static String sharepointDomain = "DOMAIN";

  // Shared Documents folder root
  static String sharedDocumentsRoot = "http://sharepoint.server.com/sites/IdSite/Shared Documents/";

  // WS Uri
  static String defaultWSUri = "http://sharepoint.server.com/sites/IdSite/_vti_bin/Copy.asmx";

  /**
   * Note: Setting credentials with AuthScope.ANY authentication scope (null value for host and/or realm) is
   * highly discouraged in production applications.
   * @param args
   * @throws Exception
   */
  public static void main(String... args) throws Exception {

    // XMLBeans request object
    CopyIntoItemsDocument request = CopyIntoItemsDocument.Factory.newInstance();
    CopyIntoItems cii = request.addNewCopyIntoItems();
    DestinationUrlCollection duc = DestinationUrlCollection.Factory.newInstance();
    duc.addNewString().setStringValue(sharedDocumentsRoot + "SomeFolder/test.txt");
    cii.setDestinationUrls(duc);
    cii.addNewFields().addNewFieldInformation();

    // Sample file
    String fileContent = "";
    FileInputStream fis = new FileInputStream(new File("c:/temp/test.txt"));
    while (fis.available() > 0) {
      byte[] buffer = new byte[fis.available()];
      fis.read(buffer);
      fileContent = fileContent + new String(buffer);
    }
    cii.setStream(Base64.encode(fileContent.getBytes()));

    // MOSS WS Copy File invocation with SOAP Action CopyIntoItems
    System.out.println(new UploadFileMOSSWS().
        callWs(request, "http://schemas.microsoft.com/sharepoint/soap/CopyIntoItems"));

  }

  /**
   * Generic Spring WS Client
   * @param input
   * @param soapAction
   * @return
   */
  private XmlObject callWs(XmlObject input, String soapAction) {

    XmlObject result = null;

    // WS Client
    WebServiceTemplate wst = getWebServiceTemplate();
    XmlBeansMarshaller marshaller = new XmlBeansMarshaller();
    wst.setMarshaller(marshaller);
    wst.setUnmarshaller(marshaller);
    wst.setDefaultUri(defaultWSUri);

    // HTTP Client configuration
    HttpClient client = new HttpClient();
    client.getParams().setAuthenticationPreemptive(true);
    client.getHostConfiguration().setProxy(proxyHost, proxyPort);
    client.getState().setProxyCredentials(AuthScope.ANY,
          new UsernamePasswordCredentials(proxyUser, proxyPass));
    Credentials defaultcreds =
          new NTCredentials(sharepointUser, sharepointPass, "localhost", sharepointDomain);
    client.getState().setCredentials(AuthScope.ANY, defaultcreds);
    CommonsHttpMessageSender messageSender = new CommonsHttpMessageSender(client);
    wst.setMessageSender(messageSender);

    // WS invocation with SOAP Action
    result = (XmlObject)wst.marshalSendAndReceive(input, new SoapActionCallback(soapAction));

    return result;

    }

}

WebSphere 6.1 web service client using SSL

It’s hard to develop web services using native WebSphere 6.1 support without the aid of IBM developing tools such as Application Server Toolkit or Rational Application Developer. Even it’s hard to find, download and install these tools.

IBM provides a bunch of detailed information and manuals on every product, but this fact does not guarantee sometimes an easy way to desired solution.

How to invoke a web service using SSL? The response to this question can be found on many places: IBM Redbooks,  some articles from IBM,  official product documentation… And all of them base the solution on the use of Rational Application Developer to modify XML web service descriptor ibm-webservicesclient-bnd.xmi. This should be fine, if Rational Application Developer were a free tool.

To avoid the use of this product, XML manual modification it’s also possible according to this information. Just only including a reference to a WebSphere Application Server SSL Configuration makes the work:


I’ve never understand IBM’s vision, in my opinion information must be sufficient but not extensive.