Axis2 支援兩種二進制數據類型:byte[] 與 javax.activation.DataHandler。無論服務端使用哪種,wsdl2java 生成的 Java Stub 皆統一映射為 DataHandler;而 .NET、Delphi 等平台則映射為 byte[]。這是因為 DataHandler 為 Java 特有 API。
package service;
import java.io.*;
import javax.activation.DataHandler;
public class FileService {
// 使用 byte[] 上傳
public boolean uploadWithByte(byte[] file, String filename) {
try (FileOutputStream fos = new FileOutputStream(filename)) {
fos.write(file);
return true;
} catch (Exception e) {
return false;
}
}
// 使用 DataHandler 上傳
public boolean uploadWithDataHandler(DataHandler file, String filename) {
try (FileOutputStream fos = new FileOutputStream(filename)) {
writeInputStreamToFile(file.getInputStream(), fos);
return true;
} catch (Exception e) {
return false;
}
}
private void writeInputStreamToFile(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[8192];
int n;
while ((n = is.read(buffer)) > 0) {
os.write(buffer, 0, n);
}
}
}
<service name="fileService">
<description> 文件服務 </description>
<parameter name="ServiceClass"> service.FileService </parameter>
<messageReceivers>
<messageReceiver mep="https://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
</service>
// 建立 DataHandler
DataHandler dh = new DataHandler(new FileDataSource(imagePath));
// 封裝參數(wsdl2java 會為每個方法生成對應的 Wrapper 類)
UploadWithByte uwb = new UploadWithByte();
uwb.setFile(dh);
// 調用
FileServiceStub fss = new FileServiceStub();
fss.uploadWithByte(uwb);
MemoryStream ms = new MemoryStream();
Bitmap bitmap = new Bitmap(picUpdateImage.Image);
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
service.fileService fs = new WSC.service.fileService();
// C# 兩種方法參數皆為 byte[]
fs.uploadWithDataHandler(ms.ToArray());
fs.uploadWithByte(ms.ToArray());
若需傳輸大檔案,建議改用 FTP 等專用協議,Web Service 僅傳遞檔案元資料(如檔名、路徑),以提升效率並避免記憶體壓力。
利用 Java 序列化傳遞物件(byte[] 經 ObjectOutputStream)僅限於客戶端與服務端均為 Java 的情況;.NET 的序列化格式不相容,跨平台請改用 XML/JSON 等中性格式。