Потоковая передача ввода/вывода JBoss

У меня есть дело с приложением на основе Spring MVC, развернутым под JBoss-4.2.3.GA, и я хочу уточнить, как работает потоковая передача ввода/вывода сервлета с огромным телом запросов/ответов. Я беспокоюсь об этом, потому что не хочу хранить весь запрос/ответ в памяти до тех пор, пока вызов не будет полностью завершен.

Как я могу точно определить реализацию потока ввода/вывода, которую JBoss передает сервлету? Или, возможно, я могу исследовать его поведение в какой-то спецификации?

Спасибо за любую полезную информацию об этом.


person Raman    schedule 31.03.2011    source источник


Ответы (1)


API сервлета по умолчанию не хранит все тело запроса и ответа в памяти. Это фактически ваш собственный код обработки/анализа, который делает это.

Что касается тела запроса, то при его обработке не следует держать все тело в byte[]. Каждый байт byte[] потребляет, да, один байт памяти Java. Вы должны попытаться (пере) написать свой код таким образом, чтобы он никогда не удерживал все тело в памяти. Обрабатывайте его, например, построчно или буфер за буфером и/или передавайте его немедленно в OutputStream.

Например. когда тело основано на символе:

BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(someOutputStream, "UTF-8"));

for (String line; (line = reader.readLine()) != null;) {
    processIfNecessary(line);
    writer.writeln(line);
}

или когда тело основано на байтах:

BufferedInputStream input = new BufferedInputStream(request.getInputStream());
BufferedOutputStream output = new BufferedOutputStream(someOutputStream);
byte[] buffer = new byte[1024]; // 1KB buffer.

for (int length; (length = input.read(buffer)) > 0;) {
    processIfNecessary(buffer);
    output.write(buffer, 0, length);
}

Что касается тела ответа, то оно будет храниться в памяти до заполнения буфера. Все, что превышает размер буфера, будет сброшено. Размер буфера по умолчанию обычно составляет 2 КБ. Это настраивается на уровне сервера приложений и с помощью ServletResponse#setBufferSize() . Когда вы установите слишком большой размер буфера, он сожрет память.

person BalusC    schedule 31.03.2011