5.測試
FileTransferClient.java
package sample;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import org.apache.axiom.attachments.utils.IOUtils;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMText;
import org.apache.axiom.soap.SOAP11Constants;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
public class FileTransferClient {
private static EndpointReference targetEPR =
new EndpointReference("http://127.0.0.1:8080/axis2/services/FileOperation");
public static boolean upload(String fileName, File file, String fileType) {
try {
OMElement data = buildUploadEnvelope(fileName, file, fileType);
Options options = buildOptions();
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
System.out.println("The data in method upload: "+data);
OMElement ome = sender.sendReceive(data);
System.out.println("Convert the data to element in method upload: "+ome);
String b = ome.getText();
return Boolean.parseBoolean(b);
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}
public static boolean download(String userName, String fileName, String fileType) {
try {
OMElement data = buildDownloadEnvelope(userName, fileName, fileType);
Options options = buildOptions();
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
System.out.println("The data in method download: "+data);
OMElement ome = sender.sendReceive(data);
System.out.println("Convert the data to element in method download: "+ome);
OMText binaryNode = (OMText) ome.getFirstOMChild();
binaryNode.setOptimize(true); //必須加此句,否則會出現ContentID is null的異常!
DataHandler actualDH = (DataHandler) binaryNode.getDataHandler();
FileOutputStream imageOutStream = new FileOutputStream("D:/userTemp/xx.gif");
InputStream is = actualDH.getInputStream();
imageOutStream.write(IOUtils.getStreamAsByteArray(is));
return true;
}
catch(Exception e) {
e.printStackTrace();
}
return false;
}
private static OMElement buildUploadEnvelope(String fileName, File file, String fileType) {
DataHandler expectedDH;
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://example.org/filedata", "fd");
OMElement data = fac.createOMElement("upload", omNs);
OMElement fileContent = fac.createOMElement("fileContent", omNs);
FileDataSource dataSource = new FileDataSource(file);
expectedDH = new DataHandler(dataSource);
OMText textData = fac.createOMText(expectedDH, true);
fileContent.addChild(textData);
OMElement _fileName = fac.createOMElement("fileName", omNs);
_fileName.setText(fileName);
OMElement _fileType = fac.createOMElement("fileType", omNs);
_fileType.setText(fileType);
data.addChild(_fileName);
data.addChild(_fileType);
data.addChild(fileContent);
return data;
}
private static OMElement buildDownloadEnvelope(String userName, String fileName, String fileType) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace("http://example.org/filedata", "fd");
OMElement data = fac.createOMElement("download", omNs);
OMElement _userName = fac.createOMElement("userName", omNs);
_userName.setText(userName);
OMElement _fileName = fac.createOMElement("fileName", omNs);
_fileName.setText(fileName);
OMElement _fileType=fac.createOMElement("fileType", omNs);
_fileType.setText(fileType);
data.addChild(_userName);
data.addChild(_fileName);
data.addChild(_fileType);
return data;
}
private static Options buildOptions() throws AxisFault {
Options options = new Options();
options.setSoapVersionURI(SOAP11Constants.SOAP_ENVELOPE_NAMESPACE_URI);
options.setTo(targetEPR);
// enabling MTOM in the client side
options.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
return options;
}
public static void main(String agrs[]) {
String file = "D:/userTemp/ya.gif";
String fn = "testUser";
String ft="gif";
boolean rtv = upload(fn,new File(file),ft);
System.out.println("is upload success: "+rtv);
String un="zj";
String downfn="1";
if(download(un,downfn,ft)){
System.out.println("download success.");
}
else System.out.println("download fail.");
System.out.println("Client main end.");
}
}
|
6.結果
察看soap消息,我們可以發現
<fd:upload xmlns:fd="http://example.org/filedata">
<fd:fileName>testUser</fd:fileName>
<fd:fileType>gif</fd:fileType>
<fd:fileContent>RHQMLJJ4/AMZkEBAEAOw(省略部分2進制代碼)</fd:fileContent>
</fd:upload>
Convert the data to element in method upload:
<fd:response xmlns:fd=http://example.org/filedata xmlns:tns="http://ws.apache.org/axis2">true</fd:response>
The data in method download:
<fd:download xmlns:fd="http://example.org/filedata">
<fd:userName>zj</fd:userName>
<fd:fileName>1</fd:fileName>
<fd:fileType>gif</fd:fileType>
</fd:download>
Convert the data to element in method download:
<fd:response xmlns:fd="http://example.org/filedata" xmlns:tns="http://ws.apache.org/axis2">
eIqGRwjkQAAAOw==(省略部分2進制代碼)
</fd:response>
|
7.代碼分析
利用Axis2的Mtom發送附件應用了builder模式。要向一個webserive 發送請求,首先就要構建一個請求的Envelope,Axis2構建Envelope的時候是利用的Axis2的AXIOM api(就是axis2的java object和xml的映射處理機制),其編程模式和DOM差不多的.看這一段:
private static OMElement buildUploadEnvelope(String mailboxnum, short greetingType, File file, String FileType) {
DataHandler expectedDH;
OMFactory fac = OMAbstractFactory.getOMFactory();
...
return data;
}
|
這一段其實是構建的data對像是這樣一段xml的java object代表:
<fd:upload xmlns:fd="http://example.org/filedata">
<fd:fileName>testUser</fd:fileName>
<fd:fileType>gif</fd:fileType>
<fd:fileContent>RHQMLJJ4/AMZkEBAEAOw(省略部分2進制代碼)</fd:fileContent>
</fd:upload>
|
其中的Dwvc2VydmljZT4NCjwvZGVwbG95bWVudD4NCg0K是要傳送的文件的內容代表,至于什么編碼,我沒有深究。注意這一句:
OMElement data = fac.createOMElement("upload", omNs);
|
這里的“upload”參數對應的是webservice的一個操作的名稱,這個操作的名稱是跟webservice的server端實現類的方法名和services.xml的所定義的
<operationname="upload">
<actionMapping>urn:upload</actionMapping>
<messageReceiverclass="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
|
要一致的。
再看看這一段,
private static Options buildOptions() {
Options options = new Options();
...
return options;
}
|
這里構建的Options對象,顧名思義就是調用webservice的相應的選項:比如這里就指定了Soap協議為1.1 版,指定了所請求的service 的EPR(就是地址),聲明在client應用MTOM指定傳輸協議為HTTP。
構建好要傳送的data和options后,所執行的代碼為:
ServiceClient sender = new ServiceClient();
//設定選項
sender.setOptions(options);
//打印要傳送的數據,為一段xml
System.out.println(data);
//傳送數據,得到返回值
OMElement ome = sender.sendReceive(data);
//打印返回值,為一段xml
System.out.println(ome);
//析取返回值中的數據
String b = ome.getText();
//返回
return Boolean.parseBoolean(b);
|
可以發現,server端和client的中間傳遞數據都是通過 org.apache.axiom.om.OMElement對象的,這個對象是一段xml的java 對象映射。