【发布时间】:2016-03-25 00:46:39
【问题描述】:
我们有一个用例,我们必须通过 http 将大型数据文件从环境 A 传输到环境 B。我们想要实现的是发送方以块的形式发送数据,而接收者开始以块的形式将其写入文件中。因此我们决定使用 MTOM。
网络服务代码:
@MTOM(enabled = true, threshold=1024)
@WebService(portName = "fileUploadPort", endpointInterface = "com.cloud.receiver.FileUploadService", serviceName = "FileUploadService")
@BindingType(value = SOAPBinding.SOAP12HTTP_MTOM_BINDING)
public class FileUploadServiceImpl implements FileUploadService {
@Override
public void uploadFile(FileUploader Dfile) {
DataHandler handler = Dfile.getFile();
try {
InputStream is = handler.getInputStream();
OutputStream os = new FileOutputStream(new File(absolutePath));
byte[] b = new byte[10000000];
int bytesRead = 0;
while ((bytesRead = is.read(b)) != -1) {
os.write(b, 0, bytesRead);
}
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户代码:
public static void main(String args[]) throws Exception {
URL url = new URL("http://localhost:8080/CloudReceiver/FileUploadService?wsdl");
QName qname = new QName("http://receiver.cloud.com/", "FileUploadService");
Service service = Service.create(url, qname);
FileUploadService port = service.getPort(FileUploadService.class);
// enable MTOM in client
BindingProvider bp = (BindingProvider) port;
SOAPBinding binding = (SOAPBinding) bp.getBinding();
binding.setMTOMEnabled(true);
FileUploader f = new FileUploader();
DataSource source = new FileDataSource(new File("G:\\Data\\Sender\\temp.csv"));
DataHandler dh = new DataHandler(source);
Map<String, Object> ctxt = ((BindingProvider) port).getRequestContext();
// Marking Chunk size at Client.
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 100);
f.setFile(dh);
port.uploadFile(f);
}
当我们传输小于 100MB 的数据时,一切正常。 超过 (100MB+) 应用服务器 (JBoss 8.2) 的数据文件在接收器端抛出以下异常。
java.io.IOException: UT000020: Connection terminated as request was larger than 104857600
我知道这个错误是因为standalone.xml中的属性
<http-listener name="default" socket-binding="http" max-post-size="104857600"/>
这意味着数据不会写入块中的文件,而是保存在内存中,然后在传输完成后写入文件。
我们如何实现将数据写入块中的文件?我们不希望帖子内存增加。文件大小可以达到 1 TB。
环境: JBoss 8.2 野飞,Java 8
【问题讨论】:
-
嗨,我通过为字节数组切片文件并循环发送数组解决了这个问题,我认为客户端在单个请求中将所有通道发送到服务器。
-
如果我们必须对文件进行切片,那么 MTOM 需要什么?我觉得 MTOM 应该处理切片......切片在客户端代码中得到了很好的照顾......
-
可以添加
FileUploadService的代码吗? -
您好,如果您对其中一个答案感到满意,您介意“接受”它吗?这将有助于社区,尤其是奖励那些帮助你的人。谢谢。