Создание больших сообщений MTOM / XOP с помощью JAX-WS

У меня есть вопрос об использовании MTOM / XOP с JAX-WS. Я пишу веб-сервис, который отправляет большие объемы двоичных данных. Клиент запрашивает несколько файлов, а сервер возвращает файлы в ответе.

Я могу заставить его правильно построить ответ, чтобы он правильно реализовывал XOP, но я сталкиваюсь с проблемами, связанными с памятью, потому что он хранитвсе Ответ в памяти перед отправкой. Файлы, которые отправляет этот веб-сервис, могут получитьочень большой (например, гигабайт большой), поэтому сохранение ответа в памяти не вариант.

Этот сайт Oracle (и вместе сэтотКажется, это решает эту проблему, но я просто не понимаю этого. Я думаю, что они используютDataHandler объект для потоковой передачи запроса / ответа, но я не могу понять, как они его создают.

Я генерирую свои файлы класса JAX-WS из существующего WSDL, используяwsimport, Я использую JAX-WS RI 2.1.6 с Java 6.

Как отправить ответ по мере его создания, не сохраняя сначала все в памяти?

Заранее спасибо за вашу помощь.

ОБНОВЛЕНИЕ 12/17: Я добавил следующие атрибуты в элемент схемы в WSDL, который содержит двоичные данные. Это вызываетwsimport добавитьDataHandler Объект к классу JAXB.FileDataHandler затем может быть добавлен к ответу вместо добавления всего содержимого файла, что позволяет серверу передавать содержимое каждого файла вместо хранения их всех в памяти:

xmlns:xmime="http://www.w3.org/2005/05/xmlmime" 
xmime:expectedContentTypes="application/octet-stream"

Итак, сервер теперь правильно строит ответ, и клиент правильно сохраняет каждый файл на диск при получении запроса. Тем не менее, клиент по-прежнему читает весь ответ в память по какой-то причине.

Код сервера (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;
 }
}

Код клиента:

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();
    //...
}

Ответы на вопрос(2)

Ваш ответ на вопрос