文件下载
目的:将文件通过浏览器保存到本地,并且保证文件名不会中文乱码。
首先需要了解几个小知识。
Content-Disposition
在常规的HTTP应答中,Content-Disposition响应头指示响应的内容以何种方式展示,有两种方式,一种是内联的方式(inline),就是指响应的内容将会在 页面的一部分或整个页面中显示出来。另外一种(attachment)是通过浏览器以附件的形式下载保存到本地。
Content-Disposition: inline
Content-Disposition: attachment
Content-Disposition: attachment; filename="filename.jpg"
在multipart/form-data类型的应答消息体中,作为multipart body中的消息头,用来给出其对应字段的相关信息。各个子部分由在Content-Type 中定义的分隔符分隔。
Content-Disposition: form-data
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"
/**
* 通过响应头中的Content-Disposition属性将文件从浏览器下载到本地,
* 同时设置下载时默认显示的文件名
* @param response
* @throws IOException
*/
@RequestMapping("/downloadOne")
public void downLoadByBrowser(HttpServletResponse response) throws IOException {
String fileName="1.txt";
File file=new File("D://"+fileName);
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain");
//response.setHeader("Content-type","text/plain");
//设置为attachment
try {
response.setHeader("Content-Disposition","attachment;filename="+new String(fileName.getBytes("gb2312"),"ISO8859-1"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//设置为inline
// response.setHeader("Content-Disposition","inline")
InputStream in = new FileInputStream(file);
ServletOutputStream os = response.getOutputStream();
int len;
byte[] b =new byte[1024];
while((len=in.read(b))!=-1){
os.write(b,0,len);
}
os.close();
in.close();
}
结果图
- attachment
- inline
附 setContentType("#")和setHeader(“Content-type”:"#")
response.setContentType("text/plain");
response.setHeader("Content-type","text/plain");
二者有什么区别和联系呢?
setContentType("#")和setHeader(“Content-type”,"#")本质上是没有什么区别的,setHeader(“Content-type”,"#")本质上还是调用的setContentType("#")方法,只是在其中加入了一些判断逻辑,推荐使用setContentType()方法。
(二者区别详情见:https://springboot.io/t/topic/2013)