controller 层
@Autowired
private DownloadService service;
// 触发下载任务
@GetMapping(value = "/downloadData")
@ResponseBody
public Result<Object> downloadData(ServletRequest request,
@RequestParam(value = "userId",defaultValue = "anonymous") String userId)throws IOException {
log.info("---------------downloadData start-------------");
String rootDirectory = request.getServletContext().getRealPath("/");
log.info("rootDirectory:"+rootDirectory);
// 临时放置文件目录
Path p = Paths.get(rootDirectory, "temp");
if (!p.toFile().exists()) {
p.toFile().mkdirs();
}
this.service.createDownloadingDataTask(userId);
return Result.ok();
}
//@ApiOperation("检测下载进度")
@GetMapping(value = "/check4DownloadingData")
public Object check4DownloadingData(
@RequestParam(value = "userId",defaultValue = "anonymous") String userId) throws IOException {
Result<Object> result = this.service.check4DownloadingDataTask(wwId);
if(result.isOK()){
File file = (File) result.getResult();
// 下载成功返回二进制流
return getResponseEntity(file,null,false);
}
// ResponseEntity<String> responseEntity = ResponseEntity.ok()
// .header("Content-Type", "application/json")
// .body("Hello World");
ResponseEntity<String> responseEntity = new ResponseEntity<>(result.getMsg(), HttpStatus.OK);
return responseEntity;
}
//service 层不贴了,直接上 serviceImpl 实现类
package com.example.demo.service.impl;
import com.example.demo.service.COCReportService;
import com.example.demo.utils.Result;
import com.example.demo.utils.databricks.DatabricksTemplate;
import com.example.demo.utils.poi.render.coc.COCExcelRender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
@Service
@Slf4j
public class DownloadServiceImpl implements DownloadService {
/**
* 针对 coc 导出过程数据的文件缓存
* Map<String,File> => Map<userId,File>
*/
private static Map<String,Future<File>> cache_files = new HashMap<>();
@Override
public Future<File> createDownloadingDataTask(String userId) {
Callable<File> callable = new DownloadingDataTask(userId);
FutureTask<File> task = new FutureTask<File>(callable);
// 开始执行
new Thread(task).start();
// 保存凭证
cache_files.put(wwId,task);
return task;
}
private static class DownloadingDataTask implements Callable<File>{
private String userId;
public COCDownloadingDataTask(String userId) {
this.userId = userId;
}
@Override
public File call() throws Exception {
log.info("---------------downloadData start 2 Render.... -------------");
File file = null;
try{
// 根据自己的业务逻辑,生成 file
file =new File("");
log.info("###------------the excel file address:"+file.getAbsolutePath());
return file;
}catch (Throwable e){
log.info(e.getMessage());
return null;
}
}
}
@Override
public Result<Object> check4DownloadingDataTask(String userId) {
Future<File> future= cache_files.get(wwId);
if(future==null){
return Result.failed("当前用户不存在下载任务,无数据文件下载。");
}
if(!future.isDone()){
return Result.failed("数据文件生成中…请等待1分钟后,点击”回车“确认状态。");
}
try {
return Result.ok(future.get());
} catch (Exception e) {
log.error(e.getMessage());
return Result.failed("任务执行异常,请联系管理员查看日志。");
}
}
}