版权声明

本作品采用知识共享署名 4.0 国际许可协议进行许可。 版权声明:本文由 低调小熊猫 发表于 低调小熊猫的博客 转载声明:自由转载-非商用-非衍生-保持署名,非商业转载请注明作者及出处,商业转载请联系作者本人qq:2696284032 文章链接:https://aodeng.cc/archives/javaosszipdown

简介

阿里oss对象存储官方文档我看了,但是真实开发,还不能满足需求,阿里文件下载路径只能写死,下载文件也只能单个下载,所以自己整理了一些代码,下载时可以自己选择保存的路径,可以实现多个文件同时下载,不吹逼了,反正很厉害就是了,话不多说,上代码

代码

1.自己封装的工具包的代码 https://aodeng.cc/archives/ossutil 2.页面发送请求的代码

<td>
<a class="btn btn-mini btn-danger" style="width: 88px;height:30px;margin-top: -25px" 
href="${pageContext.request.contextPath}/pproject/ossdownfile?projectId=${projectId}">
下载
</a>
</td>

3.功能实现的代码

/**
	 * oss文件下载
	 */
	@RequestMapping("/ossdownfile")  
    public void ossdownfile(HttpServletRequest request,HttpServletResponse response,@RequestParam(value="projectId",required=false) long projectId) throws Exception{ 
		try {
			//-----------------------低调小熊猫批量下载文件------------------------//
			//获取文件名称
			String Name=pprojectService.findOne(projectId).getCheckFileName();
	        //模拟文件
	        String fileName = request.getSession().getServletContext().getRealPath("tmp/check/")+"/"+projectId+"/"+Name;  
	        // 创建临时文件
	        File zipFile = File.createTempFile("temp", ".zip");
	        FileOutputStream fps = new FileOutputStream(zipFile);
	        CheckedOutputStream csum = new CheckedOutputStream(fps, new Adler32());//注释一下Adler32(较快)和CRC32两种
	        // 用于将数据压缩成Zip文件格式
	        ZipOutputStream zos = new ZipOutputStream(csum);
	        //获取文件的name并拼接成key,下载文件
	        File f = new File(PathUtil.getRealPath()+"\\tmp\\files\\"+projectId);
			if(f.exists()){
				File[] fs = f.listFiles();
				if(null!=fs){
					for(File file0:fs){
						//善意的提醒一下,key不能以任何形式的斜杠开头
						InputStream inputStream = ossUtil.getObjectForInputStream("files/"+projectId+"/"+file0.getName()).getObjectContent();
						zos.putNextEntry(new ZipEntry(file0.getName()));//确保压缩包里面文件不同名
						int bytesRead = 0;
			            // 向压缩文件中输出数据
			            while((bytesRead=inputStream.read())!=-1){
			                zos.write(bytesRead);
			            }
			            inputStream.close();
			            zos.closeEntry();
					}					
				}
			}
			zos.close();
	        //转码,免得文件名中文乱码  
	        Name = URLEncoder.encode(Name,"UTF-8");  
	        //设置文件下载头  
	        response.addHeader("Content-Disposition", "attachment;filename=" + Name);    
	        //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型    
	        response.setContentType("application/octet-stream");
	        //写入文件
	        FileInputStream fis = new FileInputStream(zipFile);
	        BufferedInputStream buff = new BufferedInputStream(fis);
	        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); 
	        //通知浏览器以附件形式下载			
	        response.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(Name,"utf-8"));
	        byte[] car=new byte[1024];
			int L=0;
			while (L < zipFile.length()) {
	            int j = buff.read(car, 0, 1024);
	            L += j;
	            out.write(car, 0, j);
	        }
			if(out!=null){
				out.flush();
				out.close();
			}
			ossUtil.clientShutdown();
			// 删除文件
	        zipFile.delete();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
    }

善意的提示

出现这个bug的时候,其实就是连接池关闭的错误:

com.aliyun.oss.common.comm.ServiceClient Unable to execute HTTP request: Connection pool shut down

这句代码记得注释掉

client.shutdown();

**创建的ossclient一旦关闭,就不可以继续使用。另外,多个ossclient实例之间是没有影响的,关闭任意一个,其余的实例不受影响。使用多线程的方式可以同时开启多个连接池,这样关闭才是没有影响的 **

**下面是两个测试Case,第一个case不断的创建、关闭,测试是OK的,第二个case会出现异常信息。 **

        public void testMuliInstanceClient() throws Exception { 
         
        Thread thrd0 = new Thread(new Runnable() { 
            final String keyPrefix = "thread0-"; 
             
            @Override 
            public void run() { 
                for (int i = 0; i < 100; i++) { 
                    OSSClient client0 = new OSSClient(SECOND_ENDPOINT, SECOND_ACCESS_ID, SECOND_ACCESS_KEY); 
                    InputStream content = TestUtils.genFixedLengthInputStream(128 * 1024); 
                    String key = TestUtils.buildObjectKey(keyPrefix, i); 
                     
                    try { 
                        PutObjectResult result = client0.putObject(bucketName, key, content, null); 
                        System.out.println(key + ": " + result.getETag()); 
                    } catch (Exception e) { 
                        e.printStackTrace(); 
                    } finally { 
                        if (client0 != null) { 
                            System.out.println("shutdown"); 
                            client0.shutdown(); 
                        } 
                    } 
                } 
            } 
                 
        }); 
     
        Thread thrd1 = new Thread(new Runnable() { 
            final String keyPrefix = "thread1-"; 
             
            @Override 
            public void run() { 
                for (int i = 0; i < 100; i++) { 
                    OSSClient client1 = new OSSClient(SECOND_ENDPOINT, SECOND_ACCESS_ID, SECOND_ACCESS_KEY); 
                    InputStream content = TestUtils.genFixedLengthInputStream(1 * 1024 * 1024); 
                    String key = TestUtils.buildObjectKey(keyPrefix, i); 
                     
                    try { 
                        PutObjectResult result = client1.putObject(bucketName, key, content, null); 
                        System.out.println(key + ": " + result.getETag()); 
                        Thread.sleep(50); 
                    } catch (Exception e) { 
                        e.printStackTrace(); 
                    } finally { 
                        if (client1 != null) { 
                            System.out.println("shutdown"); 
                            client1.shutdown(); 
                        } 
                    } 
                } 
            } 
                 
        }); 
         
        thrd0.start(); 
        thrd1.start(); 
        thrd0.join(); 
        thrd1.join(); 
 
    } 
 
    @Test 
    public void keepUsingAfterClose() { 
        OSSClient client = new OSSClient(SECOND_ENDPOINT, SECOND_ACCESS_ID, SECOND_ACCESS_KEY); 
        InputStream content = TestUtils.genFixedLengthInputStream(128 * 1024); 
        client.putObject(bucketName, "key0", content, null); 
         
        client.shutdown(); 
         
        content = TestUtils.genFixedLengthInputStream(128 * 1024); 
        try { 
            client.putObject(bucketName, "key0", content, null); 
        } catch (ClientException ce) { 
            System.out.println(ce.getMessage()); 
        } catch (Exception e) { 
            System.out.println(e.getMessage()); 
        } 
    }