Java 后端实现文件上传、下载、删除及打包下载

文件存储服务提供文件上传、下载、删除及打包下载的 Java SDK,详情参考《Java SDK

文件上传

StorageApi 提供上传文件方法 postObject,定义如下

方法:
    void postObject(@Param("userfile") InputStream var1, @Param"storeFileName"))
参数:
    userfile:上传文件流,必填
    storeFileName:文件存储文件名,必填,推荐按照格式“/{yyyy}/{MM}/{dd}/anoy_{文件名}”自定义

由于服务模型的参数不支持文件,因此上传文件的服务不能通过模型定义,需要手工写代码实现。

  • 定义 controller

在 model/service/main/src/main/java/main/controller 目录下添加 FileCustomController.java 文件,如下图所示

代码如下

@RestController(value="main-fileCustomController")
public class FileCustomController {

    @Autowired
    private FileUserServiceImpl fileService;

    /**
    * 请求:上传文件
    */
    @RequestMapping(value = "/main/file/upload", method = RequestMethod.POST)

    public ResponseEntity<String> upload(
            @RequestParam(name = "pid", required = true) String pid,
            @RequestParam(name = "files") List<MultipartFile> files    ) throws Exception{
        SecurityUtil.encodeAndCheck(pid);
        String resp=fileService.uploadFile(files);
        HttpHeaders headers = new HttpHeaders();
        headers.putAll(ServiceResponseUtils.getSystemHeader());
        headers.putAll(ServiceResponseUtils.getCacheControlHeader());
        headers.putAll(ServiceResponseUtils.getJsonContentTypeHeader());
        ResponseEntity<String> ret =  new ResponseEntity<String>(resp,headers,HttpStatus.OK);
        return ret;
    }
}
  • 定义 service

在 FileUserServiceImpl.java 中添加 uploadFile 方法,实现文件上传,代码如下

public String uploadFile(List<MultipartFile> files) throws Exception {
    // 获取api实例
    StorageApi storageApi = StorageClient.getInstance();
    JSONArray filesInfo = new JSONArray();
    for (MultipartFile file : files) {
        // 获取存储文件路径
        String storeFileName = "/" + org.apache.http.client.utils.DateUtils.formatDate(new Date(), "yyyy-MM-dd")
                + "/" + UUID.randomUUID()
                + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
        //调用storageapi接口
        storageApi.postObject(file.getInputStream(), storeFileName, 0);
        JSONObject fileInfo = new JSONObject();
        fileInfo.put("storeFileName", storeFileName);
        fileInfo.put("realFileName", file.getOriginalFilename());
        filesInfo.add(fileInfo);
    }
    //返回上传文件信息,用于存储及文件访问等后续操作
    return filesInfo.toJSONString();
}

前端页面通过附件组件文件上传的 action 定义如下

action: this.getServiceUrl("/main/file/upload")

文件下载

StorageApi 提供下载文件方法 getFileAsFeignResponse,定义如下

方法:
    Response getFileAsFeignResponse(@Param("storeFileName") String var1,@Param("realFileName") String var3)
参数:
    storeFileName:存储文件名,必填  
    realFileName:文件实际使用名,非必填
描述:
    后端获取文件响应信息
返回值:
    Response:文件响应信息

添加文件下载服务,如下图所示

在 FileUserServiceImpl.java 中添加 downloadFile 方法,实现文件下载及预览,代码如下

public void downloadFile(String storeFileName,String realFileName,String operateType) throws Exception {
    // 获取 api 实例
    StorageApi storageApi = StorageClient.getInstance();
    // 获取文件流
    Response storageResponse = storageApi.getFileAsFeignResponse(storeFileName, storeFileName, realFileName);
    InputStream inputStream = storageResponse.body().asInputStream();

    // 设置响应头
    HttpServletResponse response = SpringWebUtil.getResponse();
    if(operateType.equals("download")) {
        response.setContentType("application/octet-stream");
        String headerKey = "Content-Disposition";
        String headerValue = "attachment; filename=\"" + URLEncoder.encode(realFileName, "UTF-8") + "\"";
        response.setHeader(headerKey, headerValue);
    }
    OutputStream os = response.getOutputStream();
    // 将文件内容写入响应流
    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        os.write(buffer, 0, bytesRead);
    }
    os.close();
    inputStream.close();
}

前端页面 JS 调用文件下载的代码如下

onDownload(file) {   
    window.open(this.getServiceUrl(`/main/file/downloadfile?operateType=download&storeFileName=${file.response?.[0]?.storeFileName}&realFileName=${file.response?.[0]?.realFileName}`))
},

前端页面 JS 调用文件预览的代码如下

onPreview(file) {   
    window.open(this.getServiceUrl(`/main/file/downloadfile?operateType=preview&storeFileName=${file.response?.[0]?.storeFileName}&realFileName=${file.response?.[0]?.realFileName}`))
},

文件删除

StorageApi 提供删除文件方法 removeObject,定义如下

方法:
    void removeObject(@Param("storeFileName") String var1)
参数:
    storeFileName:存储文件名,必填

添加删除文件服务,如下图所示

在 FileUserServiceImpl.java 中添加 deleteFile 方法,实现删除文件,代码如下

public String deleteFile(String storageFileName) throws Exception {   
    // 获取 api 实例
    StorageApi storageApi = StorageClient.getInstance();

    // 删除文件
    storageApi.removeObject(storageFileName);
    return "ok";
}

前端页面 JS 调用删除文件的代码如下

async onRemove(file) {
    try {
        let url = this.getServiceUrl("/main/file/deletefile");
        let { data } = await this.request({ url, data: { storageFileName: file.response?.[0]?.storeFileName }, method: "post" });
        if (data == "ok") {
            message.info("删除成功");
        } else {
            message.error("删除出错!");
        }
    } catch (error) {
        console.error(error);
    }
},

文件打包下载

StorageApi 提供打包下载文件方法 getBatchZipStreamAsFeignResponse,定义如下

方法:
    Response getBatchZipStreamAsFeignResponse(JSONArray var1, @Param("zipFileName") String var2)
参数:
    JSONArray var1:文件信息,必填
    zipFileName:下载文件包名,非必填,默认为“附件{yyyyMMddHHmm}.zip”
描述:
    根据传递的文件集合信息进行打包下载
返回值:
    Response:文件响应信息

添加打包下载服务,如下图所示

在 FileUserServiceImpl.java 中添加 downloadPackage 方法,实现文件打包下载,代码如下

public void downloadPackage(String files, String zipFileName) throws Exception {
    // 获取文件信息
    JSONArray filesArr = JSON.parseArray(files);

    // 获取api实例
    StorageApi storageApi = StorageClient.getInstance(RequestType.APPLICTION_JSON);
    // 获取zip包输入流
    Response storageResponse = storageApi.getBatchZipStreamAsFeignResponse(filesArr, zipFileName);
    InputStream inputStream = storageResponse.body().asInputStream();

    // 设置响应头
    HttpServletResponse response = SpringWebUtil.getResponse();
    response.setContentType("application/zip");
    String headerKey = "Content-Disposition";
    String headerValue = "attachment; filename=\"" + URLEncoder.encode(zipFileName, "UTF-8") + "\"";
    response.setHeader(headerKey, headerValue);
    // 将文件内容写入响应流
    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = inputStream.read(buffer)) != -1) {
        response.getOutputStream().write(buffer, 0, bytesRead);
    }
    inputStream.close();
}

前端页面 JS 调用文件打包下载的代码如下

const zipDownload = async () => {
    let files = [];
    this.fileList?.forEach(item => files.push(...item.response || []));
    if (files.length == 0) {
        message.error("请先上传文件");
        return;
    }
    window.open(this.getServiceUrl(`/main/file/downloadpackage?zipFileName=${decodeURIComponent("自定义组件多文件打包下载.zip")}&files=${encodeURIComponent(JSON.stringify(files))}`));
}

案例位置

桌面-页面-文件处理组件-附件组件.w

图 2

results matching ""

    No results matching ""