如何在返回 HTTP 代码后通知客户端异常

How to notify exception to client after HTTP code is returned

我使用 Java 和 Spring 框架在 REST 控制器 class 中创建绑定到 GET 请求的方法。

但是,此方法返回的结果作为流发送,由另一个服务(使用 InfluxDB)异步提供。

因此,它会立即 returns 向客户端发送代码 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 服务器的远程连接和 returns 数据的 InputStream。此客户端的默认超时为 10 秒。

如果没有太多数据,一切正常,客户端会下载包含正确数据的 CSV。

但是如果 InfluxDB 服务器没有及时响应(数据太多),即使返回 HTTP 代码 200,也会下载一个空的 CSV 文件。

事情是,当我调试时,它通过 FileCopyUtils.copy 行,其中 returns 200, 但 10 秒后它通过 "throw new DataAnalysisException" 捕获-堵塞。但是此时客户端已经下载了一个空的CSV,得到了code 200

DataAnalysisException 是返回 HTTP 代码 500 的自定义异常。

我的问题是:超时后,有没有办法通知客户我们实际上遇到了问题,即使他得到了 200? 这可以帮助我建立一个错误页面通知他。

谢谢大家。

我解决了

我使用了 StreamUtils.copy 而不是 FileCopyUtils.copy,这基本上是一样的,只是它不会自动关闭输入和输出流。

然后,在 catch 子句中,我执行 response.reset() 然后 response.sendError(code, "msg"),然后抛出异常。

并且在 finally 子句中,我手动关闭了输入流和输出流。

因此,CSV headers 和剩余数据被清除,当流关闭时它不会告诉浏览器下载 CSV 文件。

如果您需要更多信息或精确代码,请随时与我联系。