Создание больших сообщений 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); //