带参数的网络文件下载

一、需求详述

    需要针对在网络上的资源文件下载到本地保存,并且需要在下载文件前设置请求参数。此时的请求是POST类型。

二、代码实现

    /**
     * @Description : 根据参数下载文件
     * @Date : 2018/7/11 16:51
     * @Author : Licf
     * @Modified By : Licf
     */
    public static File downloadFileByParam(String urlPath, String downloadDir, Map params) {
        // 构建请求body参数
        StringBuffer sb = new StringBuffer();
        if (params != null) {
            for (Entry e : params.entrySet()) {
                sb.append(e.getKey());
                sb.append("=");
                sb.append(e.getValue());
                sb.append("&");
            }
            sb.substring(0, sb.length() - 1);
        }

        File file = null;
        try {
            // 统一资源
            URL url = new URL(urlPath);
            // 连接类的父类,抽象类
            URLConnection urlConnection = url.openConnection();
            // http的连接类
            HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
            // 发送POST请求必须设置如下两行
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            // 设定请求的方法,默认是GET
            httpURLConnection.setRequestMethod("POST");
            // 设置请求字符编码
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
/*            打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。
            调用connect()方法只是建立连接,并不会向服务器传递数据,只用调用getRespconseCode()方法时(有博文说是getInputStream()才会向服务器传递数据,getResponseCode中会调用getInputStream方法)。
            跟着getResponseCode()源码发现里面调用了getInputStream()方法,在getInputStream()方法中会判断当前是否连接,如果没有连接,则调用connect()方法建立连接。*/
            httpURLConnection.connect();

            //按照指定编码设置body参数
            OutputStreamWriter osw = new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8");
            osw.write(sb.toString());
            osw.flush();
            osw.close();
            
            //构建带缓冲的流,可以一次读很多字节,但不向磁盘中写入,只是先放到内存里。等凑够了缓冲区大小的时候一次性写入磁盘,这种方式可以减少磁盘操作次数,速度就会提高很多
            BufferedInputStream bin = new BufferedInputStream(httpURLConnection.getInputStream());
            
            //System.out.println(httpURLConnection.getContentLength());
            //获取下载文件名
            String fullName = httpURLConnection.getHeaderField("Content-Disposition").trim();
            fullName = fullName.substring(fullName.lastIndexOf("=") + 1, fullName.length());

            //设置下载路径及名称
            String path = downloadDir + File.separatorChar + fullName;
            file = new File(path);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            OutputStream out = new FileOutputStream(file);
            int size = 0;
            int len = 0;
            byte[] buf = new byte[1024*64];
            while ((size = bin.read(buf)) != -1) {
                len += size;
                out.write(buf, 0, size);
                // 打印下载百分比
                System.out.println("已下载:" + len/1024 + "KB");
            }
            //BufferedOutputStream写完数据后,要调用flush()方法或close()方法,强行将缓冲区中的数据写出。否则可能无法写出数据。
            bin.close();
            out.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            return file;
        }
    }
调用如下:
        //组装session_id下载图片到本地
        //组装请求
        Map requestMap = new HashMap<>();
        requestMap.put("session_id", sessionId);
        requestMap.put("goods_sn", String.valueOf(id));
        requestMap.put("goods_size", type);

        File file = HttpClientUtil.downloadFileByParam(GlobalVars.huabanDownloadUrl,GlobalVars.uploadFolder + id, requestMap);

你可能感兴趣的:(Java)