我使用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服务器没有及时回答(数据过多),则即使返回HTTP代码200,也会下载一个空的CSV文件。
事情是,当我调试时,它通过FileCopyUtils.copy行,该行返回200,但在10秒钟后,它通过了“ throw new DataAnalysisException”捕获块。但是目前,客户端已经下载了一个空的CSV并获得了代码200。
DataAnalysisException是一个自定义异常,返回HTTP代码500。
我的问题是:在超时后,有没有办法通知客户即使他有200欧元,我们实际上还是有问题?这可以帮助我建立一个错误页面来通知他。
谢谢大家。
答案 0 :(得分:0)
我解决了。
我使用StreamUtils.copy代替FileCopyUtils.copy,它基本上是相同的东西,只是它不会自动关闭输入和输出流。
然后,在catch子句中,我执行response.reset()然后执行response.sendError(code,“ msg”),并引发异常。
在finally子句中,我手动关闭输入和输出流。
因此,将清除CSV标头和剩余数据,并且当流关闭时,它不会告诉浏览器下载CSV文件。
如果您需要更多信息或精确的代码,请随时与我联系。