云平台(一)

实现阿里云OSS进行多文件压缩下载,压缩包中不同的文件可以自定义放在不同的文件夹下,每个文件名和压缩包名也可以自定义

工具类如下:

public class OssClientUtils {
     // 都是配置信息oss
     public static final String END_POINT = "oss-cn-beijing.aliyuncs.com";
     private static final String ACCESS_KEY_ID = "sdfdsfsgg";
     private static final String ACCESS_KEY_SECRET = "sdfsfsfdsg";
     private static final OSSClient OSS_CLIENT;

    static {
        // 根据配置信息创建oss客户端对象
        OSS_CLIENT = new OSSClient(END_POINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }
    /**
    * 多文件自定义多级文件夹、文件名压缩下载
    * @param zipName 压缩文件下载名,例如:压缩包名称.zip,需要带zip后缀
    * @param bucketName
    * @param list 自定义内容,name:自定义下载的文件名;filePath:文件在oss存储的全路径,第一个/需要去掉
    *             dir:压缩包中文件目录路径,可以是多级目录,以/结束,不以/开头
    * @param response
    * @return void
    */
    public static void zipDownload(String zipName, String bucketName, List<Map<String, Object>> list, HttpServletResponse response){
        // 设置强制下载不打开
        response.setContentType("application/force-download");
        ZipOutputStream zos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream out = null;
        byte[] buffer = new byte[100 * 1024];
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            // 用于将数据压缩成Zip文件格式
            zos = new ZipOutputStream(baos);
            for (int j = 0; j < list.size(); j++) {
                Map<String, Object> map = list.get(j);
                // 下载的自定义文件名(包含文件后缀)
                String name = (String) map.get("name");
                /**
                 * 文件oss的路径,去掉Bucket,不能以/开头;
                 * 例如oss文件路径为:https://yigoutest.oss-cn-beijing.aliyuncs.com/food_safety/2021-01-04/1/cpu.jpg
                 * 则map中为filePath:food_safety/2021-01-04/1/cpu.jpg
                 */
                String filePath = (String) map.get("filePath");
                // 下载的自定义文件夹目录
                String dir = (String) map.get("dir");
                //bucketName需改为自己的bucketName
                OSSObject ossObject = OSS_CLIENT.getObject(bucketName, filePath);
                bis = new BufferedInputStream(ossObject.getObjectContent());
                zos.putNextEntry(new ZipEntry(dir + name));
                int i = bis.read(buffer);
                // 向压缩文件中输出数据
                while(i != -1){
                    zos.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
                zos.closeEntry();
            }
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName , "UTF-8"));
            out=new BufferedOutputStream(response.getOutputStream());
            out.write(baos.toByteArray());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

调用工具类demo如下:

   /**
     * 参考:阿里云(oss)官网api地址
     * https://help.aliyun.com/product/31815.html
     */
    @RequestMapping(value = "/zipDownload")
    public void zipDownload(HttpServletResponse response){
        List<Map<String, Object>> list = new ArrayList<>();
        Map<String, Object> map1 = new HashMap<>();
        map1.put("dir", "test/");
        map1.put("name","test.jpg");
        map1.put("filePath", "food_safety/2021-01-04/1/cpu.jpg");
        list.add(map1);
        Map<String, Object> map2 = new HashMap<>();
        map2.put("dir", "test/哈哈/");
        map2.put("name","哈哈.jpg");
        map2.put("filePath", "food_safety/2021-01-04/1/cpu.jpg");
        list.add(map2);
        Map<String, Object> map3 = new HashMap<>();
        map3.put("dir", "啧啧/");
        map3.put("name","啧啧.jpg");
        map3.put("filePath", "food_safety/2021-01-04/1/cpu.jpg");
        list.add(map3);
        Map<String, Object> map4 = new HashMap<>();
        map4.put("dir", "啧啧/tt/ss/嗯嗯/");
        map4.put("name","sfsd是搭嘎第三个.jpg");
        map4.put("filePath", "food_safety/2021-01-04/1/cpu.jpg");
        list.add(map4);
        // gunsProperties.getOssBucket() 得到的是文件存储位置的bucket
        OssClientUtils.zipDownload("压缩文件下载测试.zip", gunsProperties.getOssBucket(), list, response);
 }

  这种方式工具类下载的压缩包,采用winrar打不开,别的压缩工具可以打开,所以修改工具类如下:

public class OssClientUtils {
     // 都是配置信息oss
     public static final String END_POINT = "oss-cn-beijing.aliyuncs.com";
     private static final String ACCESS_KEY_ID = "sdfdsfsgg";
     private static final String ACCESS_KEY_SECRET = "sdfsfsfdsg";
     private static final OSSClient OSS_CLIENT;

    static {
        // 根据配置信息创建oss客户端对象
        OSS_CLIENT = new OSSClient(END_POINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }

    /**
    * 多文件自定义多级文件夹、文件名压缩下载
    * @param zipName 压缩文件下载名,例如:压缩包名称.zip,需要带zip后缀
    * @param bucketName
    * @param list 自定义内容,name:自定义下载的文件名;filePath:文件在oss存储的全路径,第一个/需要去掉
     *             dir:压缩包中文件目录路径,可以是多级目录,以/结束,不以/开头
    * @param response
    * @return void
    */
    public static void zipDownload(String zipName, String bucketName, List<Map<String, Object>> list, HttpServletResponse response){

        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        BufferedInputStream bis = null;
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName , "UTF-8"));
            ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());

            int sortNum = 0;
            for (int j = 0; j < list.size(); j++) {
                Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
                Map<String, Object> map = list.get(j);
                // 下载的自定义文件名(包含文件后缀)
                String name = (String) map.get("name");
                /**
                 * 文件oss的路径,去掉Bucket,不能以/开头;
                 * 例如oss文件路径为:https://yigoutest.oss-cn-beijing.aliyuncs.com/food_safety/2021-01-04/1/cpu.jpg
                 * 则map中为filePath:food_safety/2021-01-04/1/cpu.jpg
                 */
                String filePath = (String) map.get("filePath");
                // 下载的自定义文件夹目录
                String dir = (String) map.get("dir");
                GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, filePath, HttpMethod.GET);
                // 设置过期时间。
                request.setExpiration(expiration);
                // 生成签名URL(HTTP GET请求)。
                URL signedUrl = OSS_CLIENT.generatePresignedUrl(request);
                // 使用签名URL发送请求。
                OSSObject ossObject = OSS_CLIENT.getObject(signedUrl, new HashMap<>());

                if (ossObject != null) {
                    InputStream inputStream = ossObject.getObjectContent();
                    byte[] buffs = new byte[1024 * 10];
                    ZipEntry zipEntry = new ZipEntry(dir + name);
                    zos.putNextEntry(zipEntry);
                    bis = new BufferedInputStream(inputStream, 1024 * 10);
                    int read;
                    while ((read = bis.read(buffs, 0, 1024 * 10)) != -1) {
                        zos.write(buffs, 0, read);
                    }
                    ossObject.close();
                }
                sortNum++;
            }

            zos.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            try {
                if (null != bis) {
                    bis.close();
                }
                response.getOutputStream().flush();
                response.getOutputStream().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    
}
带着疑问去思考,然后串联,进而归纳总结,不断追问自己,进行自我辩证,像侦查嫌疑案件一样看待技术问题,漆黑的街道,你我一起寻找线索,你就是技术界大侦探福尔摩斯
原文地址:https://www.cnblogs.com/cainiao-Shun666/p/14786072.html