Java文件下载
创建html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="/downloadServlet?filename=1.jpg" >图片下载</a>
<a href="/downloadServlet?filename=哈哈啊.jpg" >中文名称图片下载</a>
<a href="/img/1.jpg" >图片下载2</a>
</body>
</html>
创建Servlet
package com.citicbank.fileDownload;
import com.citicbank.utils.DownLoadUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/downloadServlet")
public class DownServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.根据请求参数,获得文件类型
String filename = request.getParameter("filename");
//2. 获取路径
ServletContext servletContext = request.getServletContext();
String realPath = servletContext.getRealPath("/img/"+filename);
// 3.文件读取,字节流
// ServletInputStream inputStream = request.getInputStream(); 为什么不能用getInputStream
FileInputStream inputStream = new FileInputStream(realPath);
// 4.设置响应头
String mimeType = servletContext.getMimeType(filename);// 获取文件的MIME类型
response.setHeader("content-type", mimeType);
// 5.解决中文乱码问题
// 1、获取user-agent请求头
// String agent = request.getHeader("user-agent");
// System.out.println(agent);
// 2、使用工具类方法编码文件名即可
// String fileName = DownLoadUtils.getFileName3(agent, filename);
// response.setCharacterEncoding("UTF-8");
// 服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,
// 比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,
// 就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment(附件):
// response.setHeader("content-disposition", "attachment;filename="+filename);
response.setHeader("content-disposition", "attachment;filename="+(new String(filename.getBytes("UTF-8"), "ISO8859-1")));
// 6.文件送入到输出流
ServletOutputStream outputStream = response.getOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = inputStream.read(bytes))!=-1){
outputStream.write(bytes, 0, len);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
遇到的问题
- 如果文件放在web目录下创建的子文件夹,比如img,在使用
servletContext.getRealPath
的时候记得加上img,即String realPath = servletContext.getRealPath("/img/"+filename);
- 设置响应头,让浏览器弹出下载框
Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。当 Internet Explorer接收到头时,它会激活文件下载对话框,它的文件名框自动填充了头中指定的文件名。(请注意,这是设计导致的;无法使用此功能将文档保存到用户的计算机上,而不向用户询问保存位置。)
服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment:
Response.AppendHeader("Content-Disposition","attachment;filename=FileName.txt");
(备注:这样浏览器会提示保存还是打开,即使选择打开,也会使用相关联的程序比如记事本打开,而不是IE直接打开了。)
- 中文文件名支持
网上很多解决方案都不好使,其实就是一句话的事情
response.setHeader("content-disposition", "attachment;filename="+(new String(filename.getBytes("UTF-8"), "ISO8859-1")));
4. getInputStream主要是用来接收post提交上来的表单
参考
版权声明:本文为weixin_44191286原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。