一、需求详述
需要针对在网络上的资源文件下载到本地保存,并且需要在下载文件前设置请求参数。此时的请求是POST类型。
二、代码实现
/**
* @Description : 根据参数下载文件
* @Date : 2018/7/11 16:51
* @Author : Licf
* @Modified By : Licf
*/
public static File downloadFileByParam(String urlPath, String downloadDir, Map<String, String> params) {
// 构建请求body参数
StringBuffer sb = new StringBuffer();
if (params != null) {
for (Entry<String, String> 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<String, String> 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);