3

第2-3-6章 打包批量下载附件的接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云...

 1 year ago
source link: https://www.cnblogs.com/gitBook/p/16905388.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

5.6 接口开发-根据文件id打包下载附件

第2-1-2章 传统方式安装FastDFS-附FastDFS常用命令
第2-1-3章 docker-compose安装FastDFS,实现文件存储服务
第2-1-5章 docker安装MinIO实现文件存储服务-springboot整合minio-minio全网最全的资料

全套代码及资料全部完整提供,点此处下载

5.6.1 接口文档

根据文件id打包下载附件接口分两种情况进行下载:

1、如果客户端提交的文件id只有一个,则下载对应的原始文件

2、如果客户端提交的文件id有多个,则将对应的多个原始文件进行压缩,最终下载的是压缩后的文件

接口文档如下:

在这里插入图片描述

5.6.2 代码实现

第一步:在AttachmentController中提供根据文件id打包下载文件的方法

/**
* 下载一个文件或多个文件打包下载
*
* @param ids      文件id
* @param response
* @throws Exception
*/
@ApiOperation(value = "根据文件id打包下载", notes = "根据附件id下载多个打包的附件")
@GetMapping(value = "/download", produces = "application/octet-stream")
public void download(
    @ApiParam(name = "ids[]", value = "文件id 数组")
    @RequestParam(value = "ids[]") Long[] ids,
    HttpServletRequest request, HttpServletResponse response) throws Exception {
    BizAssert.isTrue(ArrayUtils.isNotEmpty(ids), 
                     BASE_VALID_PARAM.build("附件id不能为空"));
    //根据文件id下载文件
    attachmentService.download(request, response, ids);
}

第二步:在AttachmentService接口中扩展download方法

/**
* 根据文件id下载附件
*
* @param request
* @param response
* @param ids
* @throws Exception
*/
void download(HttpServletRequest request, 
              HttpServletResponse response, 
              Long[] ids) throws Exception;

第三步:在AttachmentServiceImpl实现类中实现download方法

@Autowired
private FileBiz fileBiz;

/**
* 根据文件id下载文件
* @param request
* @param response
* @param ids
* @throws Exception
*/
@Override
public void download(HttpServletRequest request, 
                     HttpServletResponse response, 
                     Long[] ids) throws Exception {
    //根据文件id查询数据库
    List<Attachment> list = 
        (List<Attachment>) super.listByIds(Arrays.asList(ids));
    down(request, response, list);
}

/**
* 文件下载
* @param request
* @param response
* @param list
* @throws Exception
*/
private void down(HttpServletRequest request, HttpServletResponse response, 
                  List<Attachment> list) throws Exception {
    if (list.isEmpty()) {
        throw BizException.wrap("您下载的文件不存在");
    }
    List<FileDO> fileDOList = 
        list.stream().map((file) ->FileDO.builder()
                                 .url(file.getUrl())
                                 .submittedFileName(file.getSubmittedFileName())
                                 .size(file.getSize())
                                 .dataType(file.getDataType())
                                 .build())
        						 .collect(Collectors.toList());
    fileBiz.down(fileDOList, request, response);
}

第四步:创建FileBiz,统一进行文件下载

package com.itheima.pinda.file.biz;

import cn.hutool.core.util.StrUtil;
import com.itheima.pinda.file.domain.FileDO;
import com.itheima.pinda.file.enumeration.DataType;
import com.itheima.pinda.file.utils.ZipUtils;
import com.itheima.pinda.utils.NumberHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件和附件的一些公共方法
 */
@Component
@Slf4j
public class FileBiz {
    /**
     * 构建新文件名称
     * @param filename
     * @param order
     * @return
     */
    private static String buildNewFileName(String filename, Integer order) {
        return StrUtil.strBuilder(filename).
            insert(filename.lastIndexOf("."), "(" + order + ")").toString();
    }

    /**
     * 下载文件
     * @param list
     * @param request
     * @param response
     * @throws Exception
     */
    public void down(List<FileDO> list, 
                     HttpServletRequest request, 
                     HttpServletResponse response) throws Exception {
        
        int fileSize = list.stream().filter(
            (file) -> file != null &&
            !DataType.DIR.eq(file.getDataType()) && 
            StringUtils.isNotEmpty(file.getUrl()))
                .mapToInt(
            		(file) -> NumberHelper.intValueOf0(file.getSize())).sum();
        
        String extName = list.get(0).getSubmittedFileName();
        if (list.size() > 1) {
            extName = StringUtils.substring(extName, 0, 
                                  StringUtils.lastIndexOf(extName, ".")) + 
                					"等.zip";
        }

        Map<String, String> map = new LinkedHashMap<>(list.size());
        Map<String, Integer> duplicateFile = new HashMap<>(list.size());
        list.stream()
                //过滤不符合要求的文件
                .filter((file) -> file != null && !DataType.DIR.eq(file.getDataType()) && StringUtils.isNotEmpty(file.getUrl()))
                //循环处理相同的文件名
                .forEach((file) -> {
                    String submittedFileName = file.getSubmittedFileName();
                    if (map.containsKey(submittedFileName)) {
                        if (duplicateFile.containsKey(submittedFileName)) {
                            duplicateFile.put(submittedFileName, duplicateFile.get(submittedFileName) + 1);
                        } else {
                            duplicateFile.put(submittedFileName, 1);
                        }
                        submittedFileName = buildNewFileName(submittedFileName, duplicateFile.get(submittedFileName));
                    }
                    map.put(submittedFileName, file.getUrl());
                });


        ZipUtils.zipFilesByInputStream(map, Long.valueOf(fileSize), extName, request, response);
    }
}

5.6.3 接口测试

第一步:启动Nacos配置中心

第二步:启动Nginx服务

第三步:启动文件服务

第四步:访问接口文档,地址为http://localhost:8765/doc.html

在这里插入图片描述

5.7 接口开发-根据业务类型/业务id打包下载

5.7.1 接口文档

根据业务类型/业务id打包下载文件接口分两种情况进行下载:

1、如果根据业务类型和业务id匹配到的文件只有一个,则下载对应的原始文件

2、如果根据业务类型和业务id匹配到的文件有多个,则将对应的多个原始文件进行压缩,最终下载的是压缩后的文件

接口文档如下:

在这里插入图片描述

5.7.2 代码实现

第一步:在AttachmentController中提供根据业务类型和业务id打包下载的方法

/**
* 根据业务类型或者业务id其中之一,或者2个同时打包下载文件
*
* @param bizIds   业务id
* @param bizTypes 业务类型
*
*/
@ApiImplicitParams({
    @ApiImplicitParam(name = "bizIds[]", value = "业务id数组", dataType = "array", paramType = "query"),
    @ApiImplicitParam(name = "bizTypes[]", value = "业务类型数组", dataType = "array", paramType = "query"),
})
@ApiOperation(value = "根据业务类型/业务id打包下载", notes = "根据业务id下载一个文件或多个文件打包下载")
@GetMapping(value = "/download/biz", produces = "application/octet-stream")
public void downloadByBiz(
    @RequestParam(value = "bizIds[]", required = false) String[] bizIds,
    @RequestParam(value = "bizTypes[]", required = false) String[] bizTypes,
    HttpServletRequest request, HttpServletResponse response) throws Exception {
    BizAssert.isTrue(!(ArrayUtils.isEmpty(bizTypes) && ArrayUtils.isEmpty(bizIds)), BASE_VALID_PARAM.build("附件业务id和业务类型不能同时为空"));
    attachmentService.downloadByBiz(request, response, bizTypes, bizIds);
}

第二步:在AttachmentService接口中扩展downloadByBiz方法

/**
* 根据业务id和业务类型下载附件
*
* @param request
* @param response
* @param bizTypes
* @param bizIds
* @throws Exception
*/
void downloadByBiz(HttpServletRequest request, HttpServletResponse response, 
                   String[] bizTypes, String[] bizIds) throws Exception;

第三步:在AttachmentServiceImpl实现类中实现downloadByBiz方法

/**
* 根据业务id和业务类型下载附件
*
* @param request
* @param response
* @param bizTypes
* @param bizIds
* @throws Exception
*/
@Override
public void downloadByBiz(HttpServletRequest request, HttpServletResponse response, String[] bizTypes, String[] bizIds) throws Exception {
    List<Attachment> list = super.list(
        Wraps.<Attachment>lbQ()
        .in(Attachment::getBizType, bizTypes)
        .in(Attachment::getBizId, bizIds));

    down(request, response, list);
}

5.7.3 接口测试

第一步:启动Nacos配置中心

第二步:启动Nginx服务

第三步:启动文件服务

第四步:访问接口文档,地址为http://localhost:8765/doc.html

在这里插入图片描述

第2-1-2章 传统方式安装FastDFS-附FastDFS常用命令
第2-1-3章 docker-compose安装FastDFS,实现文件存储服务
第2-1-5章 docker安装MinIO实现文件存储服务-springboot整合minio-minio全网最全的资料

全套代码及资料全部完整提供,点此处下载


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK