转载
文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端,所以文件下载需要IO技术将服务器端的文件读取到,然后写到response缓冲区中,然后再下载到个人客户端。
1.文件名 - 接受前端发来的文件名
获取到前端页面发送过来的要下载的文件的名字
StringfilenameValue=req.getParameter("filename");
2. ServletContext域-获取到ServletContext域对象
后面将调用此对象的一系列方法,用于获取文件路径、文件MimeType,并设置文件输出类型
ServletContextservletContext=req.getServletContext();//获取到ServletContext域对象
3.文件路径 - 获取指定文件在web项目中的路径
通过获取到ServletContext域对象的getRealPath()方法,读取download目录下文件的绝对路径
注意:download目录必须放在webContent目录下面,否则可能会找不到,导致报异常,在读取资源的时候,项目demo会直接去查找webContent下面的文件和文件夹
StringrealPath=servletContext.getRealPath("download/"+filenameValue);//获取到要下载文件在web项目中的绝对路径
4.文件MimeType - 获取文件的MimeType类型
通过获取到的 ServletContext 域对象的 getMimeType() 方法,获取到文件MimeType
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。MIME 协议指示 MIME 用户代理如何显示附加的文件。
告知浏览器文件的类型:response.setContentType(文件的MIME类型);
StringmimeType=servletContext.getMimeType(filenameValue);//获取到要下载文件的mimeType类型
5.输出类型 - 设置文件的输出类型
根据之前获取到的文件MimeType,然后通过 Response 域对象的 setContentType() 方法,设置文件的输出类型
resp.setContentType(mimeType);//设置文件的输出类型
6.设置响应头 - 确定文件是内嵌或弹出下载框
通过 Response 域对象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法设置响应头
Content-Disposition(内容处置/处理)
是MIME 协议的扩展,Content-Disposition 可以控制用户请求所得的内容存为一个文件时提供一个默认的文件名
inline 和attachment:文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
inline 表示:内嵌显示,文本和图片都可以解析,但对于文件或者视频会自动去调用成attachment,因此可以直接使用inline
attachment:弹出下载框,因为attachment是让文件以附件的形式打开,因此会调用下载,但此下载的功能并没有提示
//设置输出(下载)的文件的默认文件名为filenameValue的值,inline表示内嵌文本和图片,文件和视频会自动调用成attachment
resp.setHeader("Content-Disposition","inline;filename="+filenameValue);
7.执行输出(下载) - IO流
7.1 通过 new,创建字节输入流 FileInputStream,读取文件
7.2 通过Response域,创建Servlet的输出流,输出文件
FileInputStreamfileInputStream=newFileInputStream(realPath);
ServletOutputStream outputStream=resp.getOutputStream();
intb=0;
byte[] by=newbyte[1024*8];
while((b=fileInputStream.read(by))!=-1) {
outputStream.write(by,0, b);
}
outputStream.flush();
fileInputStream.close();
outputStream.close();//关流,response获得流会自动关闭,因此也可以不用手动关
功能实现代码
Java代码 - /demo/src/com/Download.java
packagecom;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.net.URLEncoder;
importjavax.servlet.ServletConfig;
importjavax.servlet.ServletContext;
importjavax.servlet.ServletException;
importjavax.servlet.ServletOutputStream;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclassDownloadextendsHttpServlet{
@Override
publicvoidinit(ServletConfigconfig)throwsServletException{
/**重写了Servlet的init(ServletConfig config)方法后一定要记得调用父类的init方法,
*否则在service/doGet/doPost方法中使用getServletContext()方法获取ServletContext对象时
*就会出现java.lang.NullPointerException异常
super.init(config);
}
@Override
protectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
doPost(req, resp);
}
@Override
protectedvoiddoPost(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{
/**1.接受前端页面发送过来的文件名字
*获取到前端页面发送过来的要下载的文件的名字
StringfilenameValue=req.getParameter("filename");
// filenameValue = URLEncoder.encode(filenameValue, "gbk");
/**2.获取到ServletContext域对象
*后面将调用此对象的一系列方法,用于获取文件路径、文件MimeType、文件输出类型
ServletContextservletContext=req.getServletContext();//获取到ServletContext域对象
/**3.获取指定文件在web项目中的路径
*通过获取到ServletContext域对象的getRealPath()方法,读取download目录下文件的绝对路径
* download目录必须放在webContent目录下面,否则可能会找不到,导致报异常,
*在读取资源的时候,项目demo会直接去查找webContent下面的文件和文件夹
StringrealPath=servletContext.getRealPath("download/"+filenameValue);//获取到要下载文件在web项目中的绝对路径
/**4.获取到文件MimeType
*通过获取到的ServletContext域对象的getMimeType()方法,获取到文件MimeType
* MIME (Multipurpose Internet Mail Extensions)是描述消息内容类型的因特网标准。
* MIME协议指示 MIME 用户代理如何显示附加的文件。
* MIME参考手册:http://www.w3school.com.cn/media/media_mimeref.asp
StringmimeType=servletContext.getMimeType(filenameValue);//获取到要下载文件的mimeType类型
/**5.设置文件的输出类型
* Response域对象的setContentType()方法,设置文件的输出类型
resp.setContentType(mimeType);//设置文件的输出类型
/**6.设置响应头,确定文件是内嵌或弹出下载框
*通过 Response 域对象的 setHeader("Content-Disposition","attachment;filename="+filename) 方法设置响应头,
* Content-Disposition(内容处置/处理) :
*是MIME 协议的扩展,Content-Disposition 可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,
* inline和attachment :
*文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
* inline表示:内嵌显示,文本和图片都可以解析,但对于文件或者视频会自动去调用成attachment,因此可以直接使用inline
* attachment:弹出下载框
* URLEncoder对象,将在响应回去的头,里面所代码filename的编码格式,转换为与客户端的一致的编码格式
* URLEncoder.encode(filenameValue,"utf-8");将Response响应到浏览器客户端为filenameValue的文件名,转变为utf-8的编码格式
resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(filenameValue,"utf-8"));//设置输出(下载)的文件的默认文件名为filenameValue的值,inline表示内嵌文本和图片
/**7.输出文件(下载文件)
* 7.1通过 new,创建字节输入流 FileInputStream,读取文件
* 7.2通过Response域,创建Servlet的输出流,输出文件
FileInputStreamfileInputStream=newFileInputStream(realPath);
ServletOutputStream outputStream=resp.getOutputStream();
intb=0;
byte[] by=newbyte[1024*8];
while((b=fileInputStream.read(by))!=-1) {
outputStream.write(by,0, b);
}
outputStream.flush();
fileInputStream.close();
outputStream.close();//关流,response获得流会自动关闭,因此也可以不用手动关
}
}
前端页面 jsp 代码 - /demo/WebContent/download.jsp