java实现多文件下载并生成zip文件

1、创建工具类,根据url下载文件生成字节码

private static final Logger logger = LoggerFactory.getLogger(UrlFilesToZip.class);

	// 根据文件链接把文件下载下来并且转成字节码
	public byte[] getImageFromURL(String urlPath) {
		byte[] data = null;
		InputStream is = null;
		HttpURLConnection conn = null;
		try {
			URL url = new URL(urlPath);
			conn = (HttpURLConnection) url.openConnection();
			conn.setDoInput(true);
			// conn.setDoOutput(true);
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(6000);
			is = conn.getInputStream();
			if (conn.getResponseCode() == 200) {
				data = readInputStream(is);
			} else {
				data = null;
			}
		} catch (MalformedURLException e) {
			logger.error("MalformedURLException", e);
		} catch (IOException e) {
			logger.error("IOException", e);
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				logger.error("IOException", e);
			}
			conn.disconnect();
		}
		return data;
	}

	public byte[] readInputStream(InputStream is) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int length = -1;
		try {
			while ((length = is.read(buffer)) != -1) {
				baos.write(buffer, 0, length);
			}
			baos.flush();
		} catch (IOException e) {
			logger.error("IOException", e);
		}
		byte[] data = baos.toByteArray();
		try {
			is.close();
			baos.close();
		} catch (IOException e) {
			logger.error("IOException", e);
		}
		return data;
	}

2、控制层control类

    @ResponseBody
	@RequestMapping(value = "/multiDownload")
	public void multiDownload(HttpServletRequest request, HttpServletResponse response) throws IOException{
        // 前端传参,获取参数
		String authFileStr = request.getParameter("authFileList");
		com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(authFileStr);
		List<TeacherCourseAuthFileVo> authFileList = com.alibaba.fastjson.JSONArray.parseArray(
				jsonObject.getJSONArray("authFileList").toJSONString(), TeacherCourseAuthFileVo.class);
		
		// 控制文件名编码,避免乱码
        String filename = new String("认证附件.zip".getBytes("UTF-8"), "ISO8859-1");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ZipOutputStream zos = new ZipOutputStream(bos);
        UrlFilesToZip s = new UrlFilesToZip();
        int i=1;
        for (TeacherCourseAuthFileVo authFile : authFileList) {
            // 定义生成的文件名
            zos.putNextEntry(new ZipEntry( "courseAuthFile\\" + i + "、" + authFile.getFileName()));
            // 获取文件内容
        	byte[] bytes = s.getImageFromURL(HttpProperties.getVal("imgHostUrl") + authFile.getFilePath());
        	zos.write(bytes, 0, bytes.length);
        	zos.closeEntry();
        	i++;
        }
        zos.close();
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setContentType("application/octet-stream; charset=UTF-8");
        response.addHeader("Content-Disposition", "attachment;fileName=" + filename);
        response.addHeader("Content-Length", "" + bos.toByteArray().length);
        IOUtils.write(bos.toByteArray(), response.getOutputStream());
	}

3、前端调用,直接利用window.location.href = "" 或 window.open("") 访问即可

function download() {
    	var rows = grid.getSelecteds();
    	if(rows.length == 0){
			nui.alert("请选择需要下载的附件!","温馨提示");
		}else{
			data.authFileList = rows;
			window.open("<%=contextPath%>/multiDownload?authFileList="+JSON.stringify(data));
		}
	}

4、遇到的问题

(1)后台请求需为get请求,用post暂无找到合适的实现,这就要求我们必须控制好请求参数长度,不然容易报如下错误。

          

(2)压缩文件ZipEntry中文乱码,即我们最终下载的zip文件解压后的中文文件名出现乱码。

        

原因是jar引入的问题,将引用由java.util.zip.*换成org.apache.tools.zip.*的就可以了,同时设置编码,因为java.util.zip里面没有设置编码的方法,默认为utf-8

         

设置编码

         

(3)org.apache.tools.zip 是 ant jar里面的有的项目没有该jar,引入方式如下

<dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant</artifactId>
            <version>1.9.7</version>
        </dependency> 

记录下来便于下次使用,也希望对有需要的人有所帮助~~~

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值