如何使用Spring Boot跟踪后端的文件下载进度?

时间:2017-09-08 12:31:24

标签: java spring rest spring-boot io

我有一个弹簧启动应用程序,它有一个返回字符串和文本文件的休息控制器。 我想跟踪服务器端的下载进度,并将消息推送到队列 当使用HttpServlet工作时,我只是从OutputStream对象获得HttpResponse并将字节推到套接字上,计算进度,如下所示:

    byte[] buffer = new byte[10];
    int bytesRead = -1;
    double totalBytes = 0d;
    double fileSize = file.length();

    while ((bytesRead = inStream.read(buffer)) != -1) {
        outStream.write(buffer, 0, bytesRead);
        totalBytes += bytesRead;
        queueClient.sendMessage(
                "job: " + job + "; percent complete: " + ((int) (totalBytes / fileSize) * 100));

        }

然而,有了Spring Boot,因为很多东西都发生在我的引擎盖下,我并不是百分之百确定如何接近它。

我刚开始使用Spring Boot,所以对我很轻松! 我的Controller目前看起来像这样:

@RestController
@RequestMapping("/api/v1/")
public class MyController {

    @Autowired
    QueueClient queue;

    @RequestMapping(value = "info/{id}", method = RequestMethod.GET)
    public String get(@PathVariable long id) {
        queue.sendMessage("Client requested id: " + id);
        return "You requested ID: " + id;
    }

    @RequestMapping(value = "files/{job}", method = RequestMethod.GET)
    public String getfiles(@PathVariable long job) {
        queue.sendMessage("Client requested files for job: " + job);
        return "You requested files for job " + job;
    }
}

我需要将文件从服务器传输到客户端,而不是先将整个文件加载到内存中。 Spring REST Controller可以实现这个吗? 如何访问HttpResponse对象,还是有其他方法可以访问它?

1 个答案:

答案 0 :(得分:2)

可以获取HttpResponse对象,可以按如下方式下载大文件:

@RequestMapping(value = "/files/{job}", method = RequestMethod.GET, produces=MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void downloadFile(@PathVariable("job") String job, HttpServletResponse response) {

//Configure the input stream from the job
    InputStream file = new FileInputStream(fileStoragePath + "\\" + job);

    response.setHeader("Content-Disposition", "attachment; filename=\""+job+"\"");


    int readBytes = 0;
    byte[] toDownload = new byte[100];
    OutputStream downloadStream = response.getOutputStream();

    while((readBytes = file.read(toDownload))!= -1){
        downloadStream.write(toDownload, 0, readBytes);
    }
    downloadStream.flush();
    downloadStream.close(); 
}