Creación de grandes mensajes MTOM / XOP con JAX-WS

Tengo una pregunta sobre el uso de MTOM / XOP con JAX-WS. Estoy escribiendo un servicio web que envía grandes cantidades de datos binarios. El cliente solicita una cantidad de archivos y el servidor devuelve los archivos en la respuesta.

Puedo hacerlo para generar la respuesta correctamente de manera que implemente XOP correctamente, pero me encuentro con problemas relacionados con la memoria porque almacenatodo Respuesta en memoria antes de enviarla. Los archivos que este servicio web envía pueden obtener.muy grande (como, giga-bytes grande), por lo que almacenar la respuesta en la memoria no es una opción.

Este sitio web de Oracle (y junto conéste) parece resolver este problema, pero simplemente no lo entiendo. Creo que usan unDataHandler Objeto para transmitir la solicitud / respuesta, pero no puedo entender cómo lo ejemplifican.

Estoy generando mis archivos de clase JAX-WS desde un WSDL existente usandowsimport. Estoy usando JAX-WS RI 2.1.6 con Java 6.

¿Cómo envío la respuesta cuando la estoy construyendo sin tener que almacenar primero en la memoria?

Gracias de antemano por tu ayuda.

ACTUALIZACIÓN 12/17: Agregué los siguientes atributos al elemento de esquema en el WSDL que contiene los datos binarios. Esto causawsimport para agregar unDataHandler objeto a la clase JAXB. UNAFileDataHandler luego se puede agregar a la respuesta, en lugar de agregar todo el contenido del archivo, lo que permite al servidor transmitir los contenidos de cada archivo, en lugar de guardarlos en la memoria:

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

Entonces, el servidor construye correctamente la respuesta ahora, y el cliente guarda correctamente cada archivo en el disco cuando recibe la solicitud. Sin embargo, el cliente todavía lee la respuesta completa en la memoria por alguna razón.

El código del servidor (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;
 }
}

El código del cliente:

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

Respuestas a la pregunta(2)

Su respuesta a la pregunta