JavaWeb文件下载功能的实现
1.发送请求使用原声XMLHttpRequest请求
注意不要使用ajxa请求,原因是:ajax的返回值类型是json,text,html,xml类型,或者可以说ajax的发送,接受都只能是string字符串,不能流类型,所以无法实现文件下载,强用会出现response冲突。
2.解析下载文件使用Blob对象
Blob简介
BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。 一直以来,JS都没有比较好的可以直接处理二进制的方法。而Blob的存在,允许我们可以通过JS直接操作二进制数据。
window.URL对象可以为Blob对象生成一个网络地址,结合a标签的download属性,可以实现文件的下载。
Blob对象详情链接:https://www.cnblogs.com/hhhyaaon/p/5928152.html
JS代码如下:
fd.append('path', path);
fd.append('filename', filename);
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.open('post', url, true);
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4 && xhr.status == 200) {
var blob = xhr.response;//获取返回字节数组
var csvUrl = URL.createObjectURL(blob);
var link = document.createElement('a');
link.href = csvUrl;
link.download = filename;
link.click();
}
}
xhr.send(fd);//发送请求
Java代码(通过File类,获取到文件的二进制字节流,通过IO流将文件二进制写出到前台):
@RequestMapping(value = "/api13", method = RequestMethod.POST, headers = "Accept=application/json; charset=utf-8")
public ResponseEntity<byte[]> downloadFileObject(@RequestParam("path") String path) throws IOException {
ResponseEntity<byte[]> res = null;
String path2 = URLDecoder.decode(path, "UTF-8");//解析路径
String storagetype = SystemConfig.getProp("filestorage.type");
File file = new File(syspath + path2);
if (file.exists() && file.isFile()) {
HttpHeaders headers = new HttpHeaders();
headers.setContentDispositionFormData("attachment", file.getName());
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
res = new ResponseEntity<byte[]>(FileUtil.BytesFromFile(file), headers, HttpStatus.CREATED);//将文件字节数组放到ResonseEntity中
}
return res;
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
CloseableHttpResponse response1 = null;
String api = request.getParameter("api");
String responseJson = null;
if (api.equals("1")) {
HttpPost httpPost = new HttpPost(API_DomainName + "/service19/api10");
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
String path = new String(request.getParameter("path").getBytes("iso8859-1"), "utf-8");
String path2 = URLEncoder.encode(path, "UTF-8");
String filename = new String(request.getParameter("filename").getBytes("iso8859-1"), "utf-8");
urlParameters.add(new BasicNameValuePair("path", path2));
HttpEntity postParams = new UrlEncodedFormEntity(urlParameters, "UTF-8");
httpPost.setEntity(postParams);
response1 = httpClient.execute(httpPost);
HttpEntity entity = response1.getEntity();
InputStream in = entity.getContent(); //获取文件输入流
OutputStream out = response.getOutputStream();
response.setContentType(getServletContext().getMimeType(filename));
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
// 写文件至前台
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
//关闭资源
in.close();
out.close();
httpClient.close();
httpPost.abort();
}
}