Mic*_*ael 6 java soap mtom jax-ws xop
我有一个关于在JAX-WS中使用MTOM/XOP的问题.我正在编写一个发送大量二进制数据的Web服务.客户端请求许多文件,服务器返回响应中的文件.
我能够正确地构建响应,以便正确实现XOP,但我遇到了与内存相关的问题,因为它在发送之前将整个响应存储在内存中.此Web服务发送的文件可能会变得非常大(如giga-bytes large),因此将响应存储在内存中不是一种选择.
此Oracle网站(并沿此一个),似乎解决了这个问题,但我只是不明白.我认为他们使用一个DataHandler对象来传输请求/响应,但我无法弄清楚它们如何实例化它.
我正在使用现有的WSDL生成我的JAX-WS类文件wsimport.我正在使用JAX-WS RI 2.1.6和Java 6.
我如何在建立响应时发送响应而不必先存储在内存中?
在此先感谢您的帮助.
更新12月17日:我将以下属性添加到包含二进制数据的WSDL中的schema元素.这会导致wsimport将DataHandler对象添加到JAXB类.FileDataHandler然后可以将A 添加到响应中,而不是添加文件的全部内容,从而允许服务器流式传输每个文件的内容,而不是将它们全部保存在内存中:
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
xmime:expectedContentTypes="application/octet-stream"
Run Code Online (Sandbox Code Playgroud)
因此,服务器现在正确地构建响应,并且客户端在收到请求时正确地将每个文件保存到磁盘.但是,客户端仍然会出于某种原因将整个响应读入内存.
服务器代码(SIB):
@MTOM
@StreamingAttachment(parseEagerly = true, memoryThreshold = 4000000L)
@WebService(...)
public class DownloadFilesPortTypeImpl implements DownloadFilesPortType {
@Override
public FileSetResponseType downloadFileSet(FileSetRequestType body) {
FileSetResponseType response = new FileSetResponseType();
for (FileRequest freq : body.getFileRequest()){
try{
//find the file on disk
File file = findFile(freq.getFileId());
//read the file data into memory
byte[] fileData;
{
FileInputStream in = new FileInputStream(file);
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte buf[] = new byte[8192];
int read;
while ((read = in.read(buf)) != -1){
out.write(buf, 0, read);
}
in.close();
out.close();
fileData = out.toByteArray();
}
//add the file to the response
FileResponse fresp = new FileResponse();
fresp.setFileId(freq.getFileId());
fresp.setData(fileData); //<-- type "xs:base64Binary"
response.getFileResponse().add(fresp);
}
catch (IOException e){
}
}
return response;
}
}
Run Code Online (Sandbox Code Playgroud)
客户端代码:
DownloadFilesService service = new DownloadFilesService();
MTOMFeature mtomFeature = new MTOMFeature();
StreamingAttachmentFeature stf = new StreamingAttachmentFeature(null, true, 4000000L);
DownloadFilesPortType port = service.getDownloadFilesPortSoap12(mtomFeature, stf);
FileSetRequestType request = new FileSetRequestType();
FileRequest freq = new FileRequest();
freq.setFileId("1234");
request.getFileRequest().add(freq);
freq = new FileRequest();
freq.setFileId("9876");
request.getFileRequest().add(freq);
//...
FileSetResponseType response = port.downloadFileSet(request); //reads entire response into memory
for (FileResponse fres : response.getFileResponse()){
byte[] data = fres.getFileData();
//...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9650 次 |
| 最近记录: |