Budowanie dużych komunikatów MTOM / XOP za pomocą JAX-WS

Mam pytanie dotyczące korzystania z MTOM / XOP z JAX-WS. Piszę serwis internetowy, który wysyła duże ilości danych binarnych. Klient żąda pewnej liczby plików, a serwer zwraca pliki w odpowiedzi.

Potrafię go poprawnie zbudować, aby poprawnie implementował XOP, ale wpadam na problemy związane z pamięcią, ponieważ przechowuje onCały odpowiedź w pamięci przed wysłaniem. Pliki wysyłane przez tę usługę internetową mogą zostać pobranebardzo duże (jak gigabajty duże), więc przechowywanie odpowiedzi w pamięci nie jest opcją.

Ta strona Oracle (i wraz zten) wydaje się rozwiązywać ten problem, ale po prostu tego nie rozumiem. Myślę, że używająDataHandler obiekt, aby przesłać strumieniowo żądanie / odpowiedź, ale nie potrafię określić, w jaki sposób tworzą instancję.

Generuję pliki klas JAX-WS z istniejącego pliku WSDL za pomocąwsimport. Używam JAX-WS RI 2.1.6 z Javą 6.

Jak wysłać odpowiedź, gdy ją buduję, bez konieczności zapisywania wszystkich w pamięci?

Z góry dziękuje za twoją pomoc.

AKTUALIZACJA 12/17: Dodałem następujące atrybuty do elementu schematu w WSDL, który przechowuje dane binarne. To powodujewsimport dodać aDataHandler obiekt do klasy JAXB. ZAFileDataHandler można następnie dodać do odpowiedzi, zamiast dodawać całą zawartość pliku, pozwalając serwerowi przesyłać strumieniowo zawartość każdego pliku, zamiast trzymać je wszystkie w pamięci:

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

Serwer poprawnie buduje odpowiedź teraz, a klient poprawnie zapisuje każdy plik na dysku, gdy odbierze żądanie. Jednak klient nadal odczytuje całą odpowiedź do pamięci z jakiegoś powodu.

Kod serwera (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;
 }
}

Kod klienta:

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

questionAnswers(2)

yourAnswerToTheQuestion