Есть два принципиально разных подхода. Одним из них является истинная асинхронная доставка с использованием такого подхода, как Comet. Вы можете увидеть некоторые описания в статьях, таких как this. Я бы использовал этот подход, когда данные, которые вы предоставляете, являются естественно инкрементными - например, измерения в реальном времени от измерительных приборов. Некоторые серверы приложений Java имеют хорошую интеграцию между системами сообщений JMS и кометами в браузере.
Другой подход заключается в том, что у вас есть механизм опроса. JavaScript в браузере периодически вызывает сервер, чтобы получить статус (и, возможно, следующую порцию данных). Преимущество этого подхода состоит в том, что вы используете очень стандартную модель программирования, меньше новых вещей для изучения. Во многих случаях, например, «есть ли новые ответы на вопрос переполнения стека, над которым я работаю?» этого вполне достаточно.
Ваша задача может заключаться в определении любой полезной информации о прогрессе. Как бы вы узнали, как далеко вы прошли генерацию CSV-файла?
Если вы запускаете длительный запрос от сервлета, вполне вероятно, что вы будете эффективно раскручивать рабочий поток для выполнения этой работы. (Может быть, с использованием JMS, может быть, с использованием асинхронных рабочих) и немедленно верните браузеру ответ «Я понял». Это гарантирует, что вы не уязвимы и время ожидания ответа Http. Проблема в том, как определить текущий прогресс. Если у «работника», выполняющего работу, нет способа сообщить о ее частичном прогрессе, вам нечего сказать. Такие вещи имеют тенденцию быть очень специфичными для приложения. Некоторые задачи вполне естественно имеют точки прогресса (рассмотрим печать, мы знаем, сколько страниц нужно сделать и сколько напечатано), другие не имеют (рассмотрите возможность определения, является ли число простым - да или нет, возможно, никаких полезных промежуточных этапов)