Как уведомить клиента об исключении после возврата HTTP-кода - PullRequest
0 голосов
/ 21 января 2019

Я использую среду Java и Spring для создания внутри класса контроллера REST метода, связанного с запросами GET.

Однако результат, возвращаемый этим методом, отправляется в виде потока, который асинхронно подается другой службой (используя InfluxDB).

Таким образом, он немедленно возвращает клиенту код 200, хотя впоследствии может произойти тайм-аут или любое исключение.

Я бы хотел уведомить клиента об этом.

/**
 * InfluxDB service
 */
@Inject
InfluxDBService influxDBService;

/**
 * @return CSV file containing the data
 */
@RequestMapping(value="/dump", method=RequestMethod.GET, produces="application/csv")
public @ResponseBody void getDump(
        HttpServletResponse response,
        @RequestParam(value = "app", required = false) String appFilter,
        @RequestParam(value = "context", required = false) String contextFilter,
        @RequestParam(value = "path", required = false) String pathRegex
        ) throws DataAnalysisException {

    [...]

    InputStream dump = influxDBService.dump( ... filters after treatment ...);

    response.setContentType("application/csv");

    long currentTime = System.currentTimeMillis() / 1000;
    String fileName = "influxdb-dump_" + currentTime + ".csv";

    response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    try {
        FileCopyUtils.copy(dump, response.getOutputStream());
    } catch (IOException e) {
        throw new DataAnalysisException("Could not get output from request results", e);
    }
}

В методе dump () OkHttpClient создает удаленное соединение с сервером InfluxDB и возвращает InputStream данных. Время ожидания этого клиента по умолчанию составляет 10 секунд.

Если данных не слишком много, все работает нормально, и клиент загружает CSV с правильными данными.

Но если сервер InfluxDB не отвечает вовремя (слишком много данных), загружается пустой CSV-файл, даже если возвращается HTTP-код 200.

Дело в том, что при отладке он проходит через строку FileCopyUtils.copy, которая возвращает 200, , но через 10 секунд проходит через блок catch «throw new DataAnalysisException». Но в это время клиент уже загрузил пустой CSV и получил код 200.

DataAnalysisException - это пользовательское исключение, возвращающее HTTP-код 500.

Мой вопрос: после тайм-аута, есть ли способ сообщить клиенту, что у нас действительно была проблема, даже если он получил 200? Это могло бы помочь мне создать страницу с ошибкой, чтобы уведомить его.

Спасибо вам всем.

1 Ответ

0 голосов
/ 23 января 2019

Я решил это.

Вместо FileCopyUtils.copy я использовал StreamUtils.copy, что по сути то же самое, за исключением того, что оно не закрывает автоматически входной и выходной потоки.

Затем в предложении catch я делаю response.reset (), затем response.sendError (code, "msg") и выкидываю исключение.

И, наконец, в предложении finally я вручную закрываю потоки ввода и вывода.

Следовательно, заголовки CSV и оставшиеся данные очищаются, и когда потоки закрываются, браузер не загружает файл CSV.

Не стесняйтесь обращаться ко мне, если вам нужна дополнительная информация или точный код.

...