Frage response.flushBuffer () funktioniert nicht


Ich versuche ein Servlet für das Streaming großer Objekte zu implementieren:

    oracle.sql.BLOB blob = rs.getBLOB('obj');
    InputStream in = blob.getBinaryStream();

    int bufferSize = 1024;
    byte[] buffer = new byte[bufferSize];

    ServletOutputStream out = response.getOutputStream();

    int counter=0
    while((length=in.read(buffer)) != -1){
        out.write(buffer,0,length);
        counter++;
        if(counter % 10 == 0){
        counter=0;
        response.flushBuffer();
    }

Dieser Code soll Daten an Client Chunk von Chunck senden. Nun, was passiert, wenn ich ein großes Objekt (100 MB) streame, geht der Speicher nach oben, und der Server stirbt manchmal, wenn es mehr als einen parallelen Download / Stream gibt.

Warum das flushBuffer() werden keine Daten an den Client gesendet? Der Client erhält ein Popup-Fenster zum Öffnen / Speichern der Datei erst nach dem Schließen der Antwort.


6
2018-05-11 13:42


Ursprung


Antworten:


Sie müssen das einstellen Content-Length Header, bevor die Daten geschrieben werden, oder der Server wird gezwungen, alle Daten zu puffern, bis der Stream geschlossen wird. An diesem Punkt kann er den Wert selbst berechnen, den Header schreiben und alle Daten senden. Sobald Sie den Ausgabestream erhalten haben, bevor Sie überhaupt Daten schreiben, legen Sie die Inhaltslänge fest:

response.setHeader("Content-Length", String.valueOf(blob.length()));

Die meisten Server sind intelligent genug, um den Puffer zu diesem Zeitpunkt selbst zu spülen, so dass Sie wahrscheinlich nicht einmal anrufen müssen flushBuffer() - Obwohl es nicht weh tut.


3
2018-05-11 13:48



Zuerst benötigen Sie einen Antwortheader für die servlet Antwort, damit der Container wissen kann, nach wie vielen Bytes die Informationen enden können:

response.setHeader("Content-Length", String.valueOf(blob.length()));

1
2018-05-11 14:06